第一版是针对 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些不同之处。
第四版针对 Lua 5.3,可在 Amazon 和其他书店购买。
购买本书,您还可以帮助 支持 Lua 项目


21.2.2 – 二进制文件

简单的模型函数 io.inputio.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.