第一版是针对 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些不同之处。
第四版针对 Lua 5.3,可在 Amazon 和其他书店购买。
购买本书,您还可以帮助 支持 Lua 项目。
用 Lua 编程 | ||
第三部分。标准库 第 21 章。I/O 库 |
简单的模型函数 io.input
和 io.output
始终以文本模式打开文件(默认模式)。在 Unix 中,二进制文件和文本文件没有区别。但在某些系统(尤其是 Windows)中,必须使用特殊标志来打开二进制文件。若要处理此类二进制文件,您必须使用 io.open
,并在模式字符串中使用字母 `b
´。
Lua 中的二进制数据处理方式类似于文本。Lua 中的字符串可以包含任何字节,并且库中的几乎所有函数都可以处理任意字节。(您甚至可以在二进制数据上执行模式匹配,只要模式不包含零字节即可。如果您想匹配字节零,可以使用类 %z
代替。)
通常,您可以使用 *all
模式(读取整个文件)或模式 n(读取 n 个字节)来读取二进制数据。作为一个简单的示例,以下程序将 DOS 格式的文本文件转换为 Unix 格式(即,将回车换行符序列转换为换行符)。它不使用标准 I/O 文件(stdin
/stdout
),因为这些文件是以文本模式打开的。相反,它假定输入文件和输出文件的名称作为程序的参数提供
local inp = assert(io.open(arg[1], "rb")) local out = assert(io.open(arg[2], "wb")) local data = inp:read("*all") data = string.gsub(data, "\r\n", "\n") out:write(data) assert(out:close())您可以使用以下命令行来调用此程序
> lua prog.lua file.dos file.unix
作为另一个示例,以下程序打印二进制文件中找到的所有字符串。该程序假定字符串是任何六个或更多个有效字符的以零结尾的序列,其中有效字符是模式 validchars
接受的任何字符。在我们的示例中,它包括字母数字、标点符号和空格字符。我们使用连接和 string.rep
来创建一个模式,该模式捕获所有六个或更多个 validchars
的序列。模式末尾的 %z
匹配字符串末尾的字节零。
local f = assert(io.open(arg[1], "rb")) local data = f:read("*all") local validchars = "[%w%p%s]" local pattern = string.rep(validchars, 6) .. "+%z" for w in string.gfind(data, pattern) do print(w) end
作为最后一个示例,以下程序转储二进制文件。同样,第一个程序参数是输入文件名;输出转到标准输出。该程序以 10 个字节为一组读取文件。对于每组,它写入每个字节的十六进制表示形式,然后将该组作为文本写入,将控制字符更改为点。
local f = assert(io.open(arg[1], "rb")) local block = 10 while true do local bytes = f:read(block) if not bytes then break end for b in string.gfind(bytes, ".") do io.write(string.format("%02X ", string.byte(b))) end io.write(string.rep(" ", block - string.len(bytes) + 1)) io.write(string.gsub(bytes, "%c", "."), "\n") end假设我们将该程序存储在一个名为
vip
的文件中;如果我们使用调用将程序应用到它自身
prompt> lua vip vip它将在 Unix 机器中产生如下输出
6C 6F 63 61 6C 20 66 20 3D 20 local f = 61 73 73 65 72 74 28 69 6F 2E assert(io. 6F 70 65 6E 28 61 72 67 5B 31 open(arg[1 5D 2C 20 22 72 62 22 29 29 0A ], "rb")). ... 22 25 63 22 2C 20 22 2E 22 29 "%c", ".") 2C 20 22 5C 6E 22 29 0A 65 6E , "\n").en 64 0A d.
版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 |