如何在Lua中读取由C生成的二进制文件

我想读取另一个程序提供的32位整数二进制文件。该文件仅包含整数,没有其他字符(如空格或逗号)。用于读取此文件的C代码如下:

FILE* pf = fopen("C:/rktemp/filename.dat", "r");
int sz = width*height;
int* vals = new int[sz];
int elread = fread((char*)vals, sizeof(int), sz, pf);
for( int j = 0; j < height; j++ )
{
    for( int k = 0; k < width; k++ )
    {
        int i = j*width+k;
        labels[i] = vals[i];
    }
}
delete [] vals;
fclose(pf);

但是我不知道如何使用Lua将该文件读入数组。

我尝试使用io.read来读取此文件,但是数组的一部分看起来像这样:


Matlab代码读取此文件如下:

row = image_size(1);
colomn = image_size(2);
fid = fopen(data_path,'r');
A = fread(fid, row * colomn, 'uint32')';
A = A + 1;
B = reshape(A,[colomn, row]);
B = B';
fclose(fid);

我尝试了一个将字节转换为整数的函数,我的代码如下:

function bytes_to_int(b1, b2, b3, b4)
      if not b4 then error("need four bytes to convert to int",2) end
      local n = b1 + b2*256 + b3*65536 + b4*16777216
      n = (n > 2147483647) and (n - 4294967296) or n
      return n
end

   local sup_filename = '1.dat'
   fid = io.open(sup_filename, "r")
   st = bytes_to_int(fid:read("*all"):byte(1,4))
   print(st)

   fid:close()

但它仍无法正确读取此文件。

点赞
用户12048
用户12048

你只调用一次 bytes_to_int。你需要为每个想要读取的 int 调用它。例如:

fid = io.open(sup_filename, "rb")
while true do
  local bytes = fid:read(4)
  if bytes == nil then break end -- EOF
  local st = bytes_to_int(bytes:byte(1,4))
  print(st)
end

fid:close()
2013-12-04 13:44:58
用户17139814
用户17139814

现在您可以调用 string.unpack 来使用 Lua 语言的新功能,它具有许多格式转换选项。以下选项可能会很有用:

  • < 设置小端
  • > 设置大端
  • = 设置本机字节序
  • i[n] 有符号整数,大小为 n 个字节(默认为本机大小)
  • I[n] 无符号整数,大小为 n 个字节(默认为本机大小)

由于您的 PC 的架构未知,因此我假设要读取的数据为无符号本机字节序。

由于您正在从文件中读取二进制数据,因此应使用 io.open(sup_filename, "rb")

以下代码可能会很有用:

local fid = io.open(sup_filename, "rb")
local contents = fid:read("a")
local now
while not now or now < #contents do
  local n, now = string.unpack("=I4", contents, now)
  print(n)
end
fid:close()

另请参阅:Lua 5.4 手册

2023-02-09 11:46:54