ファイルを正面から読み取るのではなく、逆方向に読み取ることは可能でしょうか?その出力は、ファイルの後ろからファイルの前端までです。Luaを使って "後方に"ファイルを読むことは可能ですか?
EDIT:最後の行が最初に表示され、完全に後ろには表示されません。
ファイルを正面から読み取るのではなく、逆方向に読み取ることは可能でしょうか?その出力は、ファイルの後ろからファイルの前端までです。Luaを使って "後方に"ファイルを読むことは可能ですか?
EDIT:最後の行が最初に表示され、完全に後ろには表示されません。
このソリューションは、@ 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
使用法:
標準ライブラリを使用していません。しかし、最初から最後まで行単位で読むことができ、テーブルに格納してから最後の行から最初の行まで「使用する」ことができます。
これは可能ですが、面倒です。 Lua APIは、読み取り/書き込み操作が適用されるファイル内で位置を設定して取得する機能をに提供します。
したがって、「シーク」を使用して最後から小さな塊でファイルを読み取ることができます(たとえば、filesize-1024
の位置に移動し、1024
バイトを読み取り、すべての行末を見つけて、完全な行を印刷して残っている)、それをファイルの先頭までずらして続けます。主な利点は、あなたが読んでいるバッファよりもはるかに多くのメモリを使うべきではないということです(最初から読んでいるが逆の順序で印刷したい場合、ファイル全体をメモリに保存する必要があります)、それは遅くなる可能性が高いです。
完全な下位、あなたが 'sdrawkcab' を取得するよう
はい、それは
が
io
ライブラリ内の関数を定義しio.linesbackward(filename)
面倒な:-)ですか?最初に最後の行が表示されますか? –O(n)時間の複雑さが必要ですか? –
@MarcB最後の行が最初に表示されます – fishy