Lua中是否可能以“倒序”读取文件?

与其从前面读取文件,是否可能倒序读取文件?从文件的末尾到文件的开头输出。

编辑:最后一行首先显示,而不是完全倒序。

点赞
用户2196426
用户2196426

不使用标准库。但是你总是可以逐行从头到尾读取它,将其存储在表中,然后从最后一行到第一行“使用”它。

2016-06-21 15:53:30
用户1442917
用户1442917

这是可能的,但是很麻烦。Lua API 提供了 seek 函数来设置和获取读/写操作应用的文件位置。

因此,您可以使用 "seek" 从文件末尾以小块方式读取文件(例如,从 filesize-1024 位置开始查找,读取 1024 字节,找到所有行末符号,打印完整行并存储剩余部分),并继续向文件开头方向进行。主要优点是,您不需要比读取的缓冲区更多的内存(例如,如果您从开头读取,但想按相反顺序打印,您需要将整个文件存储在内存中),但它可能会很慢。

2016-06-21 17:42:14
用户1847592
用户1847592

这个解决方案基于 @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("-----------------------------------------")
2016-06-21 23:52:46