【问题标题】:How to convert TarArchiveOutputStream to byte array without saving into file system如何将 TarArchiveOutputStream 转换为字节数组而不保存到文件系统中
【发布时间】:2021-07-03 16:58:22
【问题描述】:

我有一个 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, 0, len);
        }
        tOut.closeArchiveEntry();

    }

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

【问题讨论】:

  • 你不需要,你已经有了。 ByteArrayOutputStream fOut 是包含您的字节数组的输出流。使用toByteArray()方法,见stackoverflow.com/questions/23154009/…等其他问题
  • @Progman 正如你所说,我从 fOut 获得了一个字节数组。但是新配置文件的数据没有存储在该数组中。这意味着在我的本地磁盘中的某个位置将该字节数组转换为 tar.gz 文件后,该文件的内容与前一个相同,即未添加 config.json 文件。

标签: java tar apache-commons-compress


【解决方案1】:

您已经打开了几个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();

【讨论】:

    猜你喜欢
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2011-02-04
    • 2016-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多