2015-06-14 24 views
17

Ich habe Probleme um suche gzfiles in R. ein Beispiel hier:auf einer gz Verbindung zu suchen ist unberechenbar

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 

Das m.csv.gz schafft, die R sagt sie versuchen, auf kann, und die Hilfe für seek scheint zustimmen:

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

nun kleine Sprünge, hin und her, zu funktionieren scheint, aber wenn ich einen großen Sprung versuchen, erhalte ich eine Fehlermeldung:

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 
Allerdings

wenn ich die Verbindung zurückgesetzt und wieder starten, kann ich bis 1000 bekommen, wenn ich es in 100-Byte-Schritten tun:

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

R hat einige harte Worte über die Verwendung seek unter Windows: „Die Verwendung von ' Suche 'unter Windows wird abgeraten.' aber das ist auf einer Linux-Box (R 3.1.1, 32 Bit). Ein ähnlicher Code in Python mit der Bibliothek gz funktioniert gut und sucht überall.

R 3.2.0 ist etwas informativer:

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 

Ideen? Ich habe dies jetzt als Fehlerbericht eingereicht.

Antwort

3

Dies ist nur eine begründete Vermutung: kleine Sprünge werden nur im decodierten Puffer behandelt, wenn Sie mehr als Puffergröße suchen, wird es nur eine rohe Suche ausführen, dann versucht es, gzip in der Mitte eines Chunks zu entschlüsseln Entschlüsselungsfehler, dies ist höchstwahrscheinlich ein Fehler in der R-Bibliothek. Ich schlage vor, skip statt zu suchen, da die zugrunde liegende Bibliothek nichts mehr tun kann und keinen Einfluss auf die Leistung haben wird.

Ich habe nur rfc1952 und rfc1951 überprüft, in gzip können Sie die vollständige Größe der Datei vor dem Extrahieren nur durch Lesen aller 'Mitglieder' Header und Summe aller ISIZE Felder kennen, jedoch können Sie nicht wissen, wie groß ein deflationierter Block wird ohne es zu dekodieren (die Größe jedes Symbols ist im Wörterbuch), Sie können einfach nicht wirklich einen gemeinsamen gzip-Stream suchen.

Wenn Sie wirklich ein gzip suchen wollen, müssen Sie es vorher indizieren.

diczip ist eine Bibliothek, die zusätzliche Header zum Suchen hinzufügt.

0

Wenn Sie, wie ich, gerade hierher gekommen sind, um eine gezippte Datei mit readLines zu lesen, könnten Sie versuchen, zu verwenden: readLines(gzcon(file("your_file.txt.gz", "rb"))) anstelle von readLines(gzip("your_file.txt.gz", "r")).