簡體   English   中英

在Java 8中,如何從InputStream轉到字節數組,並一路用zip壓縮流?

[英]In Java 8 how do I go from an InputStream to a byte array compressing the stream with zip along the way?

換句話說,我有:

InputStream inputStream = getInputStreamFromSource();
byte[] output = zipOutputStreamAndConvertToByteArray(inputStream);

函數zipOutputStreamAndConvertToByteArray如何實現?

private byte[] zipOutputStreamAndConvertToByteArray(InputStream inputStream)
{
    // what code goes here?
}

這將創建一個名為file的zip file

private static byte[] zipOutputStreamAndConvertToByteArray(InputStream inputStream) throws IOException {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try (ZipOutputStream zip = new ZipOutputStream(outputStream)) {
        zip.putNextEntry(new ZipEntry("file"));
        try (InputStream in = inputStream) { 
        // this try block can be replaced with IOUtils.copy or ByteStreams.copy
            byte[] buffer = new byte[4096];
            int len;
            while ((len = in.read(buffer)) > 0) {
                zip.write(buffer, 0, len);
            }
        }
        zip.closeEntry();
    }

    return outputStream.toByteArray();
}

請注意,Java 9允許顯着簡化Adam Siemion答案的解決方案:

private static byte[] zipIntoByteArray(InputStream inputStream) throws IOException {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try(ZipOutputStream zip = new ZipOutputStream(outputStream); inputStream) {
        zip.putNextEntry(new ZipEntry("file"));
        inputStream.transferTo(zip);
    }
    return outputStream.toByteArray();
}

最初的更改不是特定於Java 9的,您可以使用單個try語句管理兩個流,並且不需要關閉最后一個(唯一的)zip條目,因為在關閉流時它將自動關閉。 然后,Java 9允許您指定現有變量(例如inputStream而無需在try語句中聲明另一個變量。 此外,您可以使用transferTo將所有剩余數據從InputStream transferToOutputStream ,而無需實現復制例程。


正如Izruo在此注釋中所說,當您不需要zip文件格式的數據而只想保存一個文件時,可以直接使用DEFLATE算法來擺脫zip文件特定的開銷。 我們可以執行與上述解決方案類似的操作,只是將ZipOutputStream替換為DeflaterOutputStream ,但是還有另一種選擇,在讀取時使用DeflaterInputStream壓縮數據:

private static byte[] compressIntoByteArray(InputStream inputStream) throws IOException {
    try(DeflaterInputStream deflate = new DeflaterInputStream(inputStream)) {
        return deflate.readAllBytes();
    }
}

當具有包含壓縮數據的數組時,可以使用new InflaterInputStream(new ByteArrayInputStream(array))快速獲取InputStream解壓縮,從而復制原始輸入流的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM