如何将二进制文件读入数组
假设我有一个大小为90兆字节的文件。它没有加密,但是它是二进制的。
我想将这个文件存储到一个以字节值数组的形式来作为表格,这样我就可以按字节处理文件了。
我可以使用最多2 GB的内存,所以一些列出已处理的字节,尚未处理的字节以及处理过的字节的工具都是不错的。我并不在意处理的时间有多长。
我应该如何处理呢?
注意,由于Egor的评论,我已经扩展和重写了这个答案。
首先,您需要在二进制模式下打开文件。在Windows上,这个区别很重要,因为默认的文本模式会将行结束符从CR+LF变成C类型的换行符。您可以通过在io.open的模式参数中指定"rb"来实现此目的。
尽管您可以逐个字节地读取文件,但实际上您要以缓冲区的方式逐步处理文件。这些缓冲区可以相当大,但除非您知道自己仅处理小文件的一次性脚本,否则应避免使用file:read"*a"将整个文件读入缓冲区,因为这会造成非常大的文件会出现各种问题。
一旦您以二进制模式打开了文件,就可以使用buffer = file:read(n)读取其中一块,其中n是缓冲区中字节数的整数计数。使用一个中等大小的2的幂可能是最有效的。返回值要么为nil,要么是最多n字节的字符串。如果少于n字节,则这就是文件中的最后一个缓冲区。(然而,如果从套接字、管道或终端读取,读取少于n的字节可能只表明尚未到达数据,这取决于很多其他复杂因素,本句话中无法解释。)
buffer中的字符串可以以任何方式进行处理。只要#buffer不太大,则{buffer:byte(1,-1)}将为缓冲区中的每个字节返回一个整数字节值的数组。太大部分取决于Lua在构建时的配置方式,并且可能还取决于其他因素,例如可用内存。 #buffer > 1E6当然太大了。在下面的示例中,我使用buffer:byte(i)一次访问一个字节。这适用于任何大小的缓冲区,至少在i仍然是整数的情况下。
最后,别忘了关闭文件。
这是一个完整的轻度测试示例。它逐块读取文件,并累加所有字节的总大小和总和。然后打印大小、总和和平均字节值。
-- 将文件中的所有字节求和
local name = ...
assert(name, "Usage: "..arg[0].." filename")
file = assert(io.open(name, "rb"))
local sum, len = 0,0
repeat
local buffer = file:read(1024)
if buffer then
len = len + #buffer
for i = 1, #buffer do
sum = sum + buffer:byte(i)
end
end
until not buffer
file:close()
print("长度:",len)
print("合计:",sum)
print("平均值:", sum / len)
在我使用此示例作为输入在Windows上运行Lua 5.1.4时,它报告如下:
长度: 402
合计: 30374
平均值: 75.557213930348
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
要将字符串
s的内容分割成字节数组,请使用{s:byte(1,-1)}。