2016-06-21 6 views
4

ファイルを正面から読み取るのではなく、逆方向に読み取ることは可能でしょうか?その出力は、ファイルの後ろからファイルの前端までです。Luaを使って "後方に"ファイルを読むことは可能ですか?

EDIT:最後の行が最初に表示され、完全に後ろには表示されません。

+0

完全な下位、あなたが 'sdrawkcab' を取得するよう
はい、それは

ioライブラリ内の関数を定義しio.linesbackward(filename)面倒な:-)ですか?最初に最後の行が表示されますか? –

+0

O(n)時間の複雑さが必要ですか? –

+0

@MarcB最後の行が最初に表示されます – fishy

答えて

2

このソリューションは、@ Paul Kulchenkoの考え方に基づいています。

function io.linesbackward(filename) 
    local file = assert(io.open(filename)) 
    local chunk_size = 4*1024 
    local iterator = function() return "" end 
    local tail = "" 
    local chunk_index = math.ceil(file:seek"end"/chunk_size) 
    return 
    function() 
     while true do 
     local lineEOL, line = iterator() 
     if lineEOL ~= "" then 
      return line:reverse() 
     end 
     repeat 
      chunk_index = chunk_index - 1 
      if chunk_index < 0 then 
      file:close() 
      iterator = function() 
         error('No more lines in file "'..filename..'"', 3) 
         end 
      return 
      end 
      file:seek("set", chunk_index * chunk_size) 
      local chunk = file:read(chunk_size) 
      local pattern = "^(.-"..(chunk_index > 0 and "\n" or "")..")(.*)" 
      local new_tail, lines = chunk:match(pattern) 
      iterator = lines and (lines..tail):reverse():gmatch"(\n?\r?([^\n]*))" 
      tail = new_tail or chunk..tail 
     until iterator 
     end 
    end 
end 

使用法:

1

標準ライブラリを使用していません。しかし、最初から最後まで行単位で読むことができ、テーブルに格納してから最後の行から最初の行まで「使用する」ことができます。

4

これは可能ですが、面倒です。 Lua APIは、読み取り/書き込み操作が適用されるファイル内で位置を設定して取得する機能を​​に提供します。

したがって、「シーク」を使用して最後から小さな塊でファイルを読み取ることができます(たとえば、filesize-1024の位置に移動し、1024バイトを読み取り、すべての行末を見つけて、完全な行を印刷して残っている)、それをファイルの先頭までずらして続けます。主な利点は、あなたが読んでいるバッファよりもはるかに多くのメモリを使うべきではないということです(最初から読んでいるが逆の順序で印刷したい場合、ファイル全体をメモリに保存する必要があります)、それは遅くなる可能性が高いです。

関連する問題