我写了一个提供.tar.gz
文件的休息资源。它工作正常。我已经尝试过请求它,保存数据,解压缩(使用tar xzvf [filename]
)并获得正确的数据。
但是,我正在尝试使用java.util.zip.GZIPInputStream
和org.apache.tools.tar.TarInputStream
解压缩并解压我在JUnit测试中提供的.tar.gz
,以验证它是否自动运行。这是我的单元测试中的代码,删除了一些细节:
HttpResponse response = <make request code here>
byte[] receivedBytes = FileHelper.copyInputStreamToByteArray(response.getEntity().getContent(), true);
GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(receivedBytes));
TarInputStream tarInputStream = new TarInputStream(gzipInputStream);
TarEntry tarEntry = tarInputStream.getNextEntry();
ByteArrayOutputStream byteArrayOutputStream = null;
System.out.println("Record size: " + tarInputStream.getRecordSize());
while (tarEntry != null) // It only goes in here once
{
byteArrayOutputStream = new ByteArrayOutputStream();
tarInputStream.copyEntryContents(byteArrayOutputStream);
tarEntry = tarInputStream.getNextEntry();
}
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
byte[] archivedBytes = byteArrayOutputStream.toByteArray();
byte[] actualBytes = <get actual bytes>
Assert.assertArrayEquals(actualBytes, archivedBytes);
最终断言在字节X = (n * 512) + 1
处失败,其中n
是最大的自然数,因此n * 512 <= l
和l
是数据的长度。也就是说,我正确地获得了512字节数据的最大可能倍数,但是调试测试我可以看到所有剩余的字节都是零。因此,如果数据总量为1000字节,则archivedBytes
中的前512个字节是正确的,但最后488个字节全部为零/未设置,如果总数据为262272字节,则得到第一个262144(512 * 512)字节正确,但剩余的字节都是零。
此外,上面的tarInputStream.getRecordSize()
系统打印Record size: 512
,所以我认为这是某种方式相关的。但是,由于存档在我下载时有效,我想数据必须在那里,并且只有我缺少的东西。
使用1000字节数据进入tarInputStream.copyEntryContents(byteArrayOutputStream)
int numRead = read(buf, 0, buf.length);
numRead
是100,但是查看缓冲区,只有前512个字节非零。也许我不应该使用该方法从TarInputStream
?
如果有人知道它应该如何运作,我会非常感谢任何建议或帮助。
答案 0 :(得分:1)
您可以指定创建tar存档时要使用的输出块大小。因此,存档的大小将是块大小的倍数。由于存档大小通常不适合整数个块,因此将零添加到最后一个数据块以使其大小合适。
答案 1 :(得分:0)
事实证明我原来的问题是错的,资源代码中的错误是。写入时,我没有关闭TarOutputStream上的条目。我猜这在从服务器手动请求它时没有引起任何问题,可能是因为条目是通过连接或其他东西关闭的,但是当从单元测试请求时工作方式不同......虽然我必须承认这不会使很有意义:P
看下面我写作代码的片段,我错过了第3行。
1: tarOutputStream.putNextEntry(tarEntry);
2: tarOutputStream.write(fileRawBytes);
3: tarOutputStream.closeEntry();
4: tarOutputStream.close();
我甚至不知道TarOutputStream上有“closeEntry”这样的东西......我现在就做! :P