在 Lua 中处理管道 io
Handling piped io in Lua
我为此搜索了很多,但找不到答案。我正在尝试执行以下操作:
cat somefile.txt | grep somepattern | ./script.lua
我在 Lua 中没有找到关于处理管道 io 的单一资源,也不知道如何去做。有没有一种好方法,非骇人听闻的方法来解决它?最好缓冲以降低内存使用量,但如果那是唯一的选择,我会接受一次读取整个文件。
要是写成一个临时文件,然后加载到程序中,那真是令人失望。
提前致谢。
标准库有一个 io.stdin
和一个 io.stdout
,您可以将它们用于输入和输出而无需求助于临时文件。您还可以使用 io.read
代替 someFile:read
,默认情况下它将从标准输入读取。
http://www.lua.org/pil/21.1.html
缓冲是提供管道的操作系统的责任。写程序的时候不用太担心。
编辑:显然,当您提到缓冲时,您正在考虑读取文件的一部分,而不是将整个文件加载到一个字符串中。 io.read
可以采用数字参数从输入中读取最多一定数量的字节,如果无法读取任何字符,则返回 nil
。
local size = 2^13 -- good buffer size (8K)
while true do
local block = io.read(size)
if not block then break end
io.write(block)
end
另一个(更简单的)替代方法是 io.lines() 迭代器,但括号内没有文件名。示例:
for line in io.lines() do
print(line)
end
更新:要获得多个字符,您可以围绕它编写一个包装器。示例:
function io.chars(n,filename)
n = n or 1 --default number of characters to read at a time
local chars = ''
local wrap, yield = coroutine.wrap, coroutine.yield
return wrap(function()
for line in io.lines(filename) do
line = chars .. line .. '\n'
while #line >= n do
yield(line:sub(1,n))
line = line:sub(n+1)
end
chars = line
end
if chars ~= '' then yield(chars) end
end)
end
for text in io.chars(30) do
io.write(text)
end
我为此搜索了很多,但找不到答案。我正在尝试执行以下操作:
cat somefile.txt | grep somepattern | ./script.lua
我在 Lua 中没有找到关于处理管道 io 的单一资源,也不知道如何去做。有没有一种好方法,非骇人听闻的方法来解决它?最好缓冲以降低内存使用量,但如果那是唯一的选择,我会接受一次读取整个文件。
要是写成一个临时文件,然后加载到程序中,那真是令人失望。
提前致谢。
标准库有一个 io.stdin
和一个 io.stdout
,您可以将它们用于输入和输出而无需求助于临时文件。您还可以使用 io.read
代替 someFile:read
,默认情况下它将从标准输入读取。
http://www.lua.org/pil/21.1.html
缓冲是提供管道的操作系统的责任。写程序的时候不用太担心。
编辑:显然,当您提到缓冲时,您正在考虑读取文件的一部分,而不是将整个文件加载到一个字符串中。 io.read
可以采用数字参数从输入中读取最多一定数量的字节,如果无法读取任何字符,则返回 nil
。
local size = 2^13 -- good buffer size (8K)
while true do
local block = io.read(size)
if not block then break end
io.write(block)
end
另一个(更简单的)替代方法是 io.lines() 迭代器,但括号内没有文件名。示例:
for line in io.lines() do
print(line)
end
更新:要获得多个字符,您可以围绕它编写一个包装器。示例:
function io.chars(n,filename)
n = n or 1 --default number of characters to read at a time
local chars = ''
local wrap, yield = coroutine.wrap, coroutine.yield
return wrap(function()
for line in io.lines(filename) do
line = chars .. line .. '\n'
while #line >= n do
yield(line:sub(1,n))
line = line:sub(n+1)
end
chars = line
end
if chars ~= '' then yield(chars) end
end)
end
for text in io.chars(30) do
io.write(text)
end