是否可以反向读取文件,使输出从文件的末尾到文件的开头?
编辑:最后一行先显示,但不完全反向。
是否可以反向读取文件,使输出从文件的末尾到文件的开头?
编辑:最后一行先显示,但不完全反向。
这是可能的,但很麻烦。Lua API提供了seek函数,用于设置和获取读写操作应用于的文件位置。
所以,你可以使用“seek”从文件末尾读取小块文件(例如,将位置定位到filesize-1024
,读取1024
字节,找到所有换行符,打印完整行并存储剩余部分),并继续向后移动到文件开头。主要优点是你不需要比正在读取的缓冲区更多的内存(如果你从开头读取,但想按相反顺序打印,则需要在内存中拥有整个文件),但速度可能会较慢。
这个解决方案基于@PaulKulchenko的想法。
是的,它很繁琐:-)
在io
库中定义函数io.linesbackward(filename)
:
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
使用方法:
local filename = "your_file.txt"
print("--- backward: ---------------------------")
for line in io.linesbackward(filename) do
print(line)
end
print("--- forward: ----------------------------")
for line in io.lines(filename) do
print(line)
end
print("-----------------------------------------")
不使用标准库。但是您可以按行从头到尾阅读它,将其存储在表中,然后从最后一行开始“使用”它。