在Lua中读取整个文件

24

我想要读取一个完整的mp3文件以便读出其id3标签。但是我发现file:read("*a")似乎并不能读取整个文件,而只是一部分。因此,我尝试构建一种解决方法来获取整个文件的内容:

function readAll(file)
    local f = io.open(file, "r")
    local content = ""
    local length = 0

    while f:read(0) ~= "" do
        local current = f:read("*all")

        print(#current, length)
        length = length + #current

        content = content .. current
    end

    return content
end

对于我的测试文件,它显示执行了256个读取操作,总共读取了约113kB(整个文件约为7MB)。虽然这应该足以读取大多数id3标签,但我想知道为什么Lua会以这种方式行事(特别是在读取诸如*.obj或*.ase之类的大型文本文件时未出现此问题)。是否有关于这种行为的解释或可靠读取整个文件的解决方案?


8
你是否使用的是Windows操作系统?请确保以二进制模式打开文件(使用"io.open"时加上"rb")。 - daurnimator
1
啊,那就是重点。以前从来没有用过二进制模式。非常感谢你! - Henrik Ilgen
有人能解释一下函数f:read("*all")中的*all格式吗?它似乎等同于*a?我在lua手册https://www.lua.org/manual/5.1/manual.html#pdf-file:read中找不到相关文档。 - Liu Hao
1
根据这个回答:https://stackoverflow.com/questions/47277203/what-is-the-all-format-in-lua-fileread-means,忽略第一个字符后的所有字符(即 *a)。我猜我从 pil 的这一章节中获取了它:https://www.lua.org/pil/21.1.html,优点是(我猜)你不必记住 *a*n*l 代表什么,因为你可以将其写出来。 - Henrik Ilgen
1个回答

72

我一定是忽略了什么,但我没看出为什么需要循环。这个代码应该可以工作(但最好添加错误处理,以防无法打开文件):

function readAll(file)
    local f = assert(io.open(file, "rb"))
    local content = f:read("*all")
    f:close()
    return content
end

2
正如在我的问题评论中所看到的,@daurnimator已经发现问题是缺少了b,但还是感谢你的回答 :) 编辑:我标记了你的答案为已接受,以便向人们展示我的问题已得到解决。 - Henrik Ilgen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接