【问题标题】:How to read the number of lines in a LARGE text file effeciently如何有效地读取 LARGE 文本文件中的行数
【发布时间】:2017-09-20 12:20:15
【问题描述】:

我有一个大约 750,000 行的大型文本文件,每隔几秒就会不断更新,我希望能够实时监控行数。我能够做到这一点,但响应时间成本非常高。

function GetFileSize( filename )
  local fp = io.open( filename )
  if fp == nil then
    return nil
  end
  file = {}
  for line in fp:lines() do
    if (file[line] ~= line) then
      table.insert(file, line)
    end
  end
  d(table.size(file))
  local filesize = fp:seek( "end" )
  fp:close()
  return filesize
end

我试图得到两个东西,大小(字节)和行数。

但是,一遍又一遍地用 750,000 行填充表格,不断地从上到下读取文件,会导致相当多的处理时间。

有没有办法在不严重阻碍我的系统的情况下获取文件大小(以字节为单位)和行数。

几乎我猜我必须在函数之外创建一个永久表,您可以在其中读取文件并将行添加到表中。但是,我不知道如何阻止它每隔几秒就自我复制一次。

我应该放弃行数并坚持字节返回,因为这根本不会减慢我的速度吗?或者有没有一种有效的方法来获得两者。

谢谢!

【问题讨论】:

  • 如果您需要行数,而不是行的实际内容,则不需要将它们存储在表格中。只需计算它们。
  • 你在文件中存储了什么?每条线总是相同的长度吗?你想准确到什么程度?如果适用,total_byte_count/byte_count_per_line 会给你行数。
  • @warspyking 我不需要文件中的信息,只需要处理时间最少的行数。
  • 请重新阅读我的评论。你误会了。

标签: lua


【解决方案1】:

尝试一次读取整个文件并用gsub 计算行数。您必须测试这对您来说是否足够快。

 t = f:read("*a")
 _,n = t:gsub("\n","")

【讨论】:

  • 我认为这需要为文件内容分配 2 个缓冲区。可以使用t:gsub("\n","\n")?可能它不会分配新的内存。
【解决方案2】:

要以字节为单位获取文件大小,请使用Lua Filesystem。对于您可能想要使用 io.lines 迭代器的行数。为了更好地发挥后者的性能,在 »Lua 编程« 中描述了 a trick

local file = arg[0] -- just use the source file for demo

-- Get the file size
local lfs = assert(require"lfs")
local attr = lfs.attributes(file)
print(attr.size)

-- Get number of lines
local count = 0
for line in io.lines(file) do
   count = count + 1
end
print(count)

【讨论】:

    【解决方案3】:

    我可以建议这个解决方案。不需要读取所有大文件。

    local function char_count(str, ch)
      local n, p = 0
      while true do
        p = string.find(str, ch, p, true)
        if not p then break end
        n, p = n + 1, p + 1
      end
      return n
    end
    
    local function file_info(name, chunk_size)
      chunk_size = chunk_size or 4096
      local f, err, no = io.open(name, 'rb')
      if not f then return nil, err, no end
      local lines, size = 0, 0
      while true do
        local chunk = f:read(chunk_size)
        if not chunk then break end
        lines = lines + char_count(chunk, '\n')
        size = size + #chunk
      end
      f:close()
      return size, lines
    end
    

    但是,如果您只需要监控一个文件并计算其中的行数,则可以使用任何文件监控解决方案。我用了一个based on LibUV

    【讨论】:

      猜你喜欢
      • 2012-05-11
      • 2021-03-15
      • 1970-01-01
      • 2015-03-01
      • 2011-07-25
      • 1970-01-01
      • 2013-01-04
      相关资源
      最近更新 更多