6

これは機能します:

f = File.new("myfile").readlines
f[0] #=> "line 1"
f[21] #=> "line 22"

しかし、非常に大きなファイルがあり、数行しか読み取る必要がない場合はどうすればよいでしょうか。ファイルを配列にロードせずに、特定の行を探してRubyで読み取ることは可能ですか?

(stdin の場合のように) ストリームをランダムにシークすることはできません。確かに、ファイル全体をロードせずにこれを行う方法が必要です。

4

3 に答える 3

5

目的のために、each_lineイテレータを使用with_indexして、現在の行の行番号 (0 から数えます) を取得できます。

File.open('myfile') do |file|

  file.each_line.with_index do |line, lineno|
    case lineno
    when 0
      # line 1
    when 21
      # line 22
    end   
  end

end

の代わりに を使用しopenてブロックを渡すことによりnew、ブロック実行の最後にファイルが適切に閉じられることが保証されます。


更新このwith_indexメソッドは、使用する開始インデックスを指定するオプションの引数を受け入れるため、上記のコードは次のように記述したほうがよいでしょう。

file.each_line.with_index(1) do |line, lineno|
  case lineno
  when 1
    # line 1
  end
end
于 2013-05-24T07:20:31.993 に答える
2

Jack と toro2k の回答 (ほぼ同じ回答) を使用しましたが、自分のユースケースに合わせて変更しました。私が望むかもしれない場所:ファイルを開き、順序が常に連続しているとは限らない複数のランダムな行を探します。これは私が思いついたものです(要約):

class LazyFile
    def initialize(file)
        @content = File.new(file)
    end

    def [](lineno)
        @content.rewind if @content.lineno > lineno
        skip = lineno - @content.lineno
        skip.times { @content.readline }
        @content.readline
    end
end

file = LazyFile("myfile")
file[1001]
于 2013-05-24T08:24:31.657 に答える