2017-04-23 192 views
1

我有一个大型的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行的文件,不断地从上到下读取文件会导致相当多的处理时间。

有没有办法以字节为单位获得文件大小,但也可以获得行数,而不会严重阻碍我的系统。

非常多我猜我必须在函数之外创建一个永久表,在该函数中读取文件并将行添加到表中。但是,我不知道如何阻止它每隔几秒就重复一次。

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

谢谢!

+0

如果您需要行数,而不是行的实际内容,则不需要将它们存储在表中。只需数一数。 – tonypdmtr

+0

你在文件中存储什么?每条线总是长度相同吗?你想成为多少准确?如果适用,total_byte_count/byte_count_per_line将为您提供行数。 – warspyking

+0

@warspyking我不需要文件中的信息,只需要处理时间最少的行数。 – kalimin

回答

1

尝试立即阅读整个文件并使用gsub来计算行数。你必须测试这对你来说是否足够快。

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

我认为这需要为文件内容分配2个缓冲区。可以使用't:gsub(“\ n”,“\ n”)'?可能是它不会分配新的内存。 – moteus

0

以字节为单位使用Lua Filesystem获取文件大小。对于您可能想要使用迭代器的行数。为了更好地实现后者,请参阅»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) 
1

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

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