1

我写了一个提供.tar.gz文件的休息资源。它工作正常。我尝试过请求它、保存数据、解包(使用tar xzvf [filename]),然后我得到了正确的数据。

但是,我正在尝试使用java.util.zip.GZIPInputStreamorg.apache.tools.tar.TarInputStream解压缩和解压缩.tar.gz我在 JUnit 测试中提供的服务,以验证它是否自动工作。这是我的单元测试中的代码,删除了一些细节:

    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);

最后的断言失败,在 byte 处存在差异X = (n * 512) + 1,其中n是最大的自然数,n * 512 <= l并且l是数据的长度。也就是说,我正确地得到了 512 字节数据的最大可能倍数,但是调试测试我可以看到所有剩余的字节都为零。因此,如果数据总量为 1000 字节,则前 512 字节archivedBytes是正确的,但最后 488 字节均为零/未设置,如果总数据为 262272 字节,我将正确获得前 262144 (512*512) 字节,但其余字节再次全部为零。

另外,tarInputStream.getRecordSize()上面的系统会打印Record size: 512,所以我认为这在某种程度上是相关的。但是,由于如果我下载存档就可以工作,我猜数据肯定在那里,而且我缺少一些东西。

进入tarInputStream.copyEntryContents(byteArrayOutputStream)1000 字节数据,在

int numRead = read(buf, 0, buf.length);

numRead100,但是查看缓冲区,只有前 512 个字节是非零的。也许我不应该使用这种方法来获取数据TarInputStream

如果有人知道它应该如何工作,我将非常感谢任何建议或帮助。

4

2 回答 2

1

您可以指定创建 tar 存档时要使用的输出块大小。因此存档的大小将是块大小的倍数。由于存档大小通常不适合整个块数,因此会将零添加到最后一个数据块以使其具有正确的大小。

于 2012-10-11T10:41:14.270 回答
0

原来我原来的问题错了,错误出资源代码中。在写入 TarOutputStream 时,我没有关闭该条目。我想这在从服务器手动请求它时不会引起任何问题,可能是因为该条目已通过连接或其他东西关闭,但是在从单元测试请求时工作方式不同......尽管我必须承认这并没有很有意义:P

查看下面我编写代码的片段,我错过了第 3 行。

1: tarOutputStream.putNextEntry(tarEntry);
2: tarOutputStream.write(fileRawBytes);
3: tarOutputStream.closeEntry();
4: tarOutputStream.close();

我什至不知道 TarOutputStream 上有一个“closeEntry”之类的东西……我现在知道了!:P

于 2012-11-22T17:02:59.847 回答