【问题标题】:Seeking on a gz connection is unpredictable在 gz 连接上寻找是不可预测的
【发布时间】:2015-06-14 21:56:03
【问题描述】:

我在寻找 R 中的 gzfile 时遇到了麻烦。下面是一个示例:

set.seed(123)
m=data.frame(z=runif(10000),x=rnorm(10000))
write.csv(m,"m.csv")
system("gzip m.csv")
file.info("m.csv.gz")$size
[1] 195975

这创建了m.csv.gz,R 表示它可以寻求它,并且seek 的帮助似乎同意:

gzf=gzfile("m.csv.gz")
open(gzf,"rb")
isSeekable(gzf)
[1] TRUE

现在来回小跳似乎可以工作,但如果我尝试大跳,我会收到错误:

seek(gzf,10)
[1] 10
seek(gzf,20)
[1] 10
seek(gzf,10)
[1] 20
seek(gzf,1000)
[1] 100
Warning message:
In seek.connection(gzf, 1000) :
  seek on a gzfile connection returned an internal error

但是,如果我重置连接并重新开始,如果我以 100 字节的步长进行,我可以达到 1000:

for(i in seq(100,1000,by=100)){seek(gzf,i)}
seek(gzf,NA)
[1] 1000

R 对在 Windows 中使用 seek 有一些严厉的措辞:“不鼓励在 Windows 上使用‘seek’。”但这是在 Linux 机器上(R 3.1.1,32 位)。 python 中使用gz 库的类似代码工作正常,到处寻找。

R 3.2.0 提供的信息略多:

Warning messages:
1: In seek.connection(gzf, 1000) : invalid or incomplete compressed data
2: In seek.connection(gzf, 1000) :
  seek on a gzfile connection returned an internal error

想法?我现在已将此作为错误报告提交。

【问题讨论】:

    标签: r io gzip seek


    【解决方案1】:

    这只是一个有根据的猜测:小跳转只是在解码的缓冲区内处理,当您寻找超过缓冲区大小时,它只会执行原始寻找,然后它会尝试在导致解码的块中间解码 gzip错误,这很可能是 R 库中的错误。我建议使用skip而不是seek,因为底层库不能做更多的事情并且不会对性能产生任何影响。

    我刚刚检查了 rfc1952 和 rfc1951,在 gzip 中,您可以在提取文件之前通过读取所有“成员”标题并总结所有 ISIZE 字段来了解文件的完整大小,但是您无法知道压缩块有多大不解码(每个符号的大小都在字典中),你根本无法真正找到一个通用的 gzip 流。

    如果您真的想查找 gzip,您必须事先对其进行索引。

    dictzip 是一个添加额外标题以允许搜索的库。

    【讨论】:

      【解决方案2】:

      如果你和我一样,只是来这里阅读带有readLines 的压缩文件,你可以尝试使用:readLines(gzcon(file("your_file.txt.gz", "rb"))) 而不是readLines(gzip("your_file.txt.gz", "r"))

      【讨论】:

      • 它甚至可以这样工作:gz_con <- file("your_file.txt.gz", "rb"); readLines(gz_con, 10); readLines(gz_con, 10); # ...
      • @petermeissner 我刚刚测试了这个(在 Windows 上),看起来这不会解压缩 gzip 存档,而只是返回在二进制值对应于换行符的位置分隔的原始二进制字符串。但是,如果提供的文件实际上已经解压缩,我提供的行不会抱怨,在这种情况下,您的较短版本也可以。也许您测试过的文件已经解压缩? This can easily happen when using gzip with default parameters,你可以用head your_file.txt.gz进行测试
      • 嗯,我没有在Windows下测试过,我用的是GNU/Linux/Ubuntu_16.04。我试过的文件是压缩的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多