如何在不保存到文件系统的情况下将 TarArchiveOutputStream 转换为字节数组
How to convert TarArchiveOutputStream to byte array without saving into file system
我有一个 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();
}
如何将tarOuputStream转为字节数组?
您已经打开了几个OutputStream
实例,但您还没有关闭它们。或者更准确地说,您还没有“刷新”内容,特别是 BufferedOutputStream
实例。
BufferedOutputStream
正在使用内部缓冲区“等待”写入目标 OutputStream
的数据。它会这样做,直到有理由这样做。这些“原因”之一是调用 BufferedOutputStream.flush()
方法:
public void flush() throws IOException
Flushes this buffered output stream. This forces any buffered output bytes to be written out to the
underlying output stream.
另一个“原因”是关闭流,以便在关闭流之前写入剩余的字节。
在您的情况下,正在写入的字节仍存储在内部缓冲区中。根据您的代码结构,您可以简单地关闭您拥有的所有 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();
我有一个 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();
}
如何将tarOuputStream转为字节数组?
您已经打开了几个OutputStream
实例,但您还没有关闭它们。或者更准确地说,您还没有“刷新”内容,特别是 BufferedOutputStream
实例。
BufferedOutputStream
正在使用内部缓冲区“等待”写入目标 OutputStream
的数据。它会这样做,直到有理由这样做。这些“原因”之一是调用 BufferedOutputStream.flush()
方法:
public void flush() throws IOException
Flushes this buffered output stream. This forces any buffered output bytes to be written out to the underlying output stream.
另一个“原因”是关闭流,以便在关闭流之前写入剩余的字节。
在您的情况下,正在写入的字节仍存储在内部缓冲区中。根据您的代码结构,您可以简单地关闭您拥有的所有 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();