如何在不保存到文件系统的情况下将 TarArchiveOutputStream 转换为字节数组

问题描述

我有一个 tar.gz 文件的字节数组表示。添加配置文件后,我想获取新 tar.gz 文件的字节数组表示。我想完全在代码中完成此操作,而无需在本地磁盘上创建任何文件

下面是我的java代码

            InputStream fIn = new ByteArrayInputStream(inputBytes);
            BufferedInputStream in = new BufferedInputStream(fIn);
            GzipCompressorInputStream gzIn = new GzipCompressorInputStream(in);
            TararchiveInputStream tarInputStream = new TararchiveInputStream(gzIn);

            ByteArrayOutputStream fOut = new ByteArrayOutputStream();
            bufferedoutputstream buffOut = new bufferedoutputstream(fOut);
            GzipCompressorOutputStream gzOut = new GzipCompressorOutputStream(buffOut);
            TararchiveOutputStream TaroutputStream = new TararchiveOutputStream(gzOut);

            ArchiveEntry nextEntry;
            while ((nextEntry = tarInputStream.getNextEntry()) != null) {
                TaroutputStream.putArchiveEntry(nextEntry);
                IoUtils.copy(tarInputStream,TaroutputStream);
                TaroutputStream.closeArchiveEntry();
            }
            tarInputStream.close();
            createTararchiveEntry("config.json",configData,TaroutputStream);
            TaroutputStream.finish();
            // Convert TaroutputStream to byte array and return





    private static void createTararchiveEntry(String fileName,byte[] configData,TararchiveOutputStream tOut)
            throws IOException {

        ByteArrayInputStream baOut1 = new ByteArrayInputStream(configData);

        TararchiveEntry tarEntry = new TararchiveEntry(fileName);
        tarEntry.setSize(configData.length);
        tOut.putArchiveEntry(tarEntry);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = baOut1.read(buffer)) > 0) {
            tOut.write(buffer,len);
        }
        tOut.closeArchiveEntry();

    }

如何将TarouputStream转换为字节数组?

解决方法

您已打开多个 OutputStream 实例,但尚未关闭它们。或者更准确地说,您没有“刷新”内容,特别是 BufferedOutputStream 实例。

BufferedOutputStream 使用内部缓冲区来“等待”写入目标 OutputStream 的数据。它会这样做,直到有理由这样做为止。这些“原因”之一是调用 BufferedOutputStream.flush() 方法:

public void flush() throws IOException

刷新这个缓冲的输出流。这会强制将任何缓冲的输出字节写出到 底层输出流。

另一个“原因”是关闭流,以便在关闭流之前写入剩余的字节。

在您的情况下,写入的字节仍存储在内部缓冲区中。根据您的代码结构,您可以简单地关闭您拥有的所有 OutputStream 实例,以便最终将字节写入 ByteArrayOutputStream

tarInputStream.close();
createTarArchiveEntry("config.json",configData,tarOutputStream);
tarOutputStream.finish();
// Convert tarOutputStream to byte array and return
tarOutputStream.close();
gzOut.close();
buffOut.close();
fOut.close();

byte[] content = fOut.toByteArray();