如何从r中的gzip文件中读取一个readLines?

时间:2017-08-13 22:39:54

标签: r

我需要从gzip文件中读取小批量(一次说100个)的行,这是一个使用gzip压缩的文本文件。我使用小批量,因为每行都非常长。

但是我无法用这样的东西(我认为缓冲区没有更新):

in.con <- gzfile("somefile.txt.gz")
for (i in 1:100000) {
  chunk <- readLines(in.con,n = 100)
  # if you inspect chunk in each loop step, say with a print
  # you will find that chunk updates once or twice and then
  # keeps printing the same data.
}
close(in.con)

我如何完成类似的事情?

注意:

  1. 对于小文件,这将有效。
  2. 您需要一个非常大的文件,当您尝试多次阅读时 - 您会看到该块变量不会更新
  3. 我认为这是因为基础扫描在gzip文件上不可靠
  4. i变量只是为了限制循环 - 我不需要引用
  5. 有些评论似乎在说代码不适用于文本文件 - 我发布的结果显示不是:
  6. in.con <- file("some.file.txt", "r", blocking = FALSE)
    while(TRUE) {
      chunk <- readLines(in.con,n = 2)
      if (length(chunk)==0) break;
      print(chunk)
    }
    close(in.con)
    

    导致输出:

    [1] "1" "2"
    [1] "3" "4"
    [1] "5" "6"
    [1] "7" "8"
    [1] "9"  "10"
    

    我的版本信息是:

    platform       x86_64-apple-darwin15.6.0   
    arch           x86_64                      
    os             darwin15.6.0                
    system         x86_64, darwin15.6.0        
    status                                     
    major          3                           
    minor          4.1                         
    year           2017                        
    month          06                          
    day            30                          
    svn rev        72865                       
    language       R                           
    version.string R version 3.4.1 (2017-06-30)
    nickname       Single Candle     
    

1 个答案:

答案 0 :(得分:0)

这是gzfile()中的错误。对于大文件,如果未指定open参数,它将一遍又一遍地读取同一行。

> incon <- gzfile(zfile)
> readLines(incon,1)
[1] First line
> readLines(incon,1)
[1] First line

即使指定了open参数,它也会引起错误。

> incon <- gzfile(zfile,open="r")
> line <- readLines(incon,1)
Warning message:
In readLines(incon, 1) :
  seek on a gzfile connection returned an internal error

解决方案:作为一种解决方法,可以改用二进制读取模式下的常规file()连接并将其包装在gzcon()中:

> incon <- gzcon(file(zfile,open="rb"))
> readLines(incon,1)
[1] First line
> readLines(incon,1)
[1] Second line