【问题标题】:GZIPInputStream end-of-file sequence in BufferedReaderBufferedReader 中的 GZIPInputStream 文件结尾序列
【发布时间】:2011-09-24 06:13:49
【问题描述】:

我使用一个 Java BufferedReader 对象逐行读取一个 GZIPInputStream,它指向一个有效的 GZIP 存档,该存档包含 1,000 行 ASCII 文本,采用典型的 CSV 格式。代码如下所示:

BufferedReader buffer = new BufferedReader(new InputStreamReader(
                        new GZIPInputStream(new FileInputStream(file))));

file 是指向档案的实际 File 对象。

我通过调用阅读了所有文件

int count = 0;
String line = null;

while ((line = reader.readLine()) != null)
{
    count++;
}

阅读器按预期浏览文件,但最后它绕过第 #1000 行并再读取一行(即循环结束后 count = 1001)。

在最后一行调用 line.length() 会报告大量 (4,000+) 个字符,所有这些字符都是不可打印的 (Character.getNumericValue() 返回 -1)。

实际上,如果我执行 line.getBytes(),则生成的 byte[] 数组具有相同数量的 NULL 字符('\0')。

这看起来像是 BufferedReader 中的错误吗?

在任何情况下,任何人都可以建议绕过此行为的解决方法吗?

编辑:更奇怪的行为:读取的第一行以文件名、几个 NULL 字符('\0')和事物行用户名和组名为前缀,然后是实际文本!

编辑:我创建了一个非常简单的测试类,它至少在我的平台上重现了我上面描述的效果。

编辑:显然是误报,我得到的文件不是普通的 GZIP 而是 tar 的 GZIP,所以这就解释了,不需要进一步测试。谢谢大家!

【问题讨论】:

  • 调试方法:使用外部gzip 提取文件,并省略GZIPInputStream - 并查看提取的文件。可能是您的 gzip 文件有问题,或者 InputStreamReader 或 BufferedReader 有错误。或 GzipInputStream。
  • 您说的是一个普通的 gzip 文件,但您的代码引用了一个 tar.gz 文件。为什么?您知道 tar + gz 文件与 gzip 不同吗?
  • 既然您有问题的答案,最好接受其中一个答案,投票选出对您有帮助的答案等。
  • 离题,我必须说我真的看不出一个有效的问题应该如何被否决。的确,首先没有“错误”,因为 OP 起初并没有看到他正在尝试解析 GZIP 文件,实际上是无意中发送了 tarball。然而,这个问题是合法的和详细的,得到了​​一个有效和彻底的答案,OP 确实看到了他的错误,他很有礼貌地放弃了他在 SourceForge 上的错误报告。所以....对 OP 和答案的支持是我能做的至少.... 编辑:给 OP 的注释 - 如果它被证明有用,请接受答案...

标签: java gzip bufferedreader eof gzipinputstream


【解决方案1】:

我想我找到了你的问题。

我尝试在问题中使用您的来源重现它,并得到以下输出:

-------------------------------------
        Reading PLAIN file
-------------------------------------

Printable part of line 1:       This, is, line, number, 1

Line start (<= 25 characters): This__is__line__number__1

No NULL characters in line 1

Other information on line 1:
        Length: 25
        Bytes: 25
        First byte: 84

Printable part of line 10:      This, is, line, number, 10

Line start (<= 26 characters): This__is__line__number__10

No NULL characters in line 10

Other information on line 10:
        Length: 26
        Bytes: 26
        First byte: 84

File lines read: 10

-------------------------------------
        Reading GZIP file
-------------------------------------

Printable part of line 1:       This, is, line, number, 1

Line start (<= 25 characters): This__is__line__number__1

No NULL characters in line 1

Other information on line 1:
        Length: 25
        Bytes: 25
        First byte: 84

Printable part of line 10:      This, is, line, number, 10

Line start (<= 26 characters): This__is__line__number__10

No NULL characters in line 10

Other information on line 10:
        Length: 26
        Bytes: 26
        First byte: 84

File lines read: 10

-------------------------------------
        TOTAL READ
-------------------------------------

Plain: 10, GZIP: 10

我认为这不是你所拥有的。为什么?您正在使用 tar.gz 文件。这是tar archive format,另外还有gzip 压缩。 GZipInputStream 撤消 gzip 压缩,但对 tar 归档格式一无所知。

tar 通常用于将多个文件打包在一起 - 以未压缩的格式,但与一些元数据一起打包,这就是您所观察到的:

编辑:更奇怪的行为:读取的第一行以文件名为前缀, 几个 NULL 字符 ('\0') 和事物行用户名和组名,然后 正文如下!

如果您有tar 文件,则需要使用 tar 解码器。 How do I extract a tar file in Java? 提供了一些链接(例如使用 Ant 的 Tar 任务),还有 JTar

如果您只想发送一个文件,最好直接使用gzip 格式(这是我在测试中所做的)。

除了您希望 gzip-stream 读取 tar 格式之外,其他地方都没有错误。

【讨论】:

  • 当然。我不敢相信这是一个错误,这就是我寻求帮助的原因。再次感谢!
  • 如果您以某种方式显示您的文件,这可能会在一开始就解决。 (我在答案中添加了一些 Java tar 链接。)
猜你喜欢
  • 2021-11-20
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
  • 2022-01-20
  • 1970-01-01
相关资源
最近更新 更多