寻求gz连接是不可预测的

Spa*_*man 20 io gzip r seek

我在寻找R中的gzfiles时遇到了麻烦.这是一个例子:

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
Run Code Online (Sandbox Code Playgroud)

这就产生了m.csv.gz,R说它可以寻求,并且seek似乎同意的帮助:

gzf=gzfile("m.csv.gz")
open(gzf,"rb")
isSeekable(gzf)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

现在小跳,来回,似乎工作,但如果我尝试大跳,我得到一个错误:

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
Run Code Online (Sandbox Code Playgroud)

但是,如果我重置连接并重新启动,如果我以100字节的步骤执行此操作,则可以达到1000:

for(i in seq(100,1000,by=100)){seek(gzf,i)}
seek(gzf,NA)
[1] 1000
Run Code Online (Sandbox Code Playgroud)

R seek在Windows中使用时有一些严厉的说法:"不鼓励在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
Run Code Online (Sandbox Code Playgroud)

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

小智 3

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

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

如果您确实想寻找 gzip,则必须事先对其进行索引。

dictzip是一个添加额外标头以允许查找的库。