File 在lua中解析文件的二进制文件

File 在lua中解析文件的二进制文件,file,parsing,lua,binary,File,Parsing,Lua,Binary,我需要你的帮助。 我有一个二进制文件。我知道一个数据包以0x7E开头。我希望有一个文件的大表,然后将表拆分为多个表,每个表都以0x7E开头。 我现在开始将二进制文件转换为十六进制文件,并使用它,但我认为使用二进制文件会更容易,但我不知道如何做到这一点。 例如,二进制文件的一行: V001…ï½ï½*\ï½..E…V001…ï½*\ï½..E$V001…ï½*\ï½..E…V001…ï½*\ï½..E 这是十六进制的同一行: 56 30 30 31 07 00 00 EF BF BD EF BF

我需要你的帮助。 我有一个二进制文件。我知道一个数据包以0x7E开头。我希望有一个文件的大表,然后将表拆分为多个表,每个表都以0x7E开头。 我现在开始将二进制文件转换为十六进制文件,并使用它,但我认为使用二进制文件会更容易,但我不知道如何做到这一点。 例如,二进制文件的一行:

V001…ï½ï½*\ï½..E…V001…ï½*\ï½..E$V001…ï½*\ï½..E…V001…ï½*\ï½..E

这是十六进制的同一行:

56 30 30 31 07 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 01 45 7E 12 02 EF BF BD 00 EF BF BD 1F 56 30 31 00 00 EF BF BD EF BF BD 2A 5C EF BF BD 03 45 24 56 30 31 04 00 EF BF BD 2A 5C EF BF BD 03 02 45 13 00 00 00 56 30 30 30 30 30 30 30 07 00 00 EF BF BD 03 01 45 7E 12 02 24 00 4D EF BF

我想要这样的输出:

表1={7E 12 02 EF BF BD 00 EF BF BD 1F 56 30 31 01 00 EF BF BD 2A 5C EF BF BD 03 02 45 24 56 30 30 04 00 EF BF BD 2A 5C EF BF BD 03 02 45 13 00 00 56 30 31 07 00 EF BF BD 2A 5C EF BF BD 03 01 45}

表2={7E 12 02 24 00 4D EF BF}

我已经可以读取文件,将其转换为十六进制,并在文件中找到0x7E的数量。加上文件的长度。但是数量和长度不是必需的。另外,我认为使用字符串是错误的,因为bytellength。你能帮我解析文件吗?我也想过使用回调函数,但我不知道怎么做。我是新来的。 这就是我目前的代码:

local function read_file(path) --function read_file
 local file = io.open(path, "rb") -- r read mode and b binary mode
 if not file then return nil end
 local content = file:read "*all" -- *all reads the whole file
 file:close()
 return content
end

function string.tohex(str)
 return (str:gsub('.',function(c)
  return string.format('%02X',string.byte(c))
 end))
end

local fileContent = read_file("H:/wireshark/rstp_dtc_0.dat"); --passes file content to function read_file
inhalt = (fileContent):tohex()

s=inhalt
t={}
for k in s:gmatch"(%x%x)" do 
 table.insert(t,tonumber(k,16))
end 

function tablelength(T)
 local count = 0
 for _ in pairs (T) do count = count +1 end 
 return count 
end 

length = tablelength(t)
print(length)

counter = 0

local items = t
for _, v in pairs(items) do 
 if v == 0x7E then   
  counter = counter+1
 end 
end 

print(counter)

谢谢你的帮助

解决方案是使用
string.gmatch
从文件内容中提取以
“\x7e”


这样,您就可以使用Lua的模式匹配功能,这样您就不必编写自己的数据包逻辑。

我为我的问题找到了另一个答案

function print_table(tab)
 print("Table:") 
  for key, value in pairs(tab) do
      io.write(string.format("%02X ", value))  
  end
 print("\n") 
end

local function read_file(path, callback) 
 local file = io.open(path, "rb") 
  if not file then 
     return nil
  end
 local t = {} 
 repeat
    local str = file:read(4 * 1024)   
    for c in (str or ''):gmatch('.') do  
        if c:byte() == 0x7E then 
            callback(t) -- function print_table
            t = {}
        else
            table.insert(t, c:byte())  
        end
    end
 until not str
 file:close() 
 return t 
 end

local result = {}
function add_to_table_of_tables(t)
 table.insert(result, t) 
end

local fileContent = read_file("file.dat", print_table)

谢谢你的帮助!你能告诉我怎么打印出来吗?要查看结果,数据包是一个包含包含数字的表的表。就用一个循环?什么不清楚?是的,对不起。如果我使用本地字节={data:byte(1,#data)}会出现一个错误:堆栈溢出(字符串片太长),我能做什么?其他解决方案呢?我还没有用大文件测试过它。您的文件有多大?第二个代码段假定您已将文件内容读入本地数据。在您的情况下,这就是文件内容
function print_table(tab)
 print("Table:") 
  for key, value in pairs(tab) do
      io.write(string.format("%02X ", value))  
  end
 print("\n") 
end

local function read_file(path, callback) 
 local file = io.open(path, "rb") 
  if not file then 
     return nil
  end
 local t = {} 
 repeat
    local str = file:read(4 * 1024)   
    for c in (str or ''):gmatch('.') do  
        if c:byte() == 0x7E then 
            callback(t) -- function print_table
            t = {}
        else
            table.insert(t, c:byte())  
        end
    end
 until not str
 file:close() 
 return t 
 end

local result = {}
function add_to_table_of_tables(t)
 table.insert(result, t) 
end

local fileContent = read_file("file.dat", print_table)