0

ファイルをバイト配列に読み込むためにa、次のコードを使用しています。

file = io.open(fileName, "rb")
str = file:read("*a")
a = {str:byte(1, #str)}

これは小さなファイルではstr:byte機能しますが、1MB のファイルでは失敗し、stack overflow (string slice too long).

これらの大きなファイルを正常に読み取る別の方法はありますか?

4

3 に答える 3

1
local fileName = 'C:\\Program Files\\Microsoft Office\\Office12\\excel.exe'
local file = assert(io.open(fileName, 'rb'))
local t = {}
repeat
   local str = file:read(4*1024)
   for c in (str or ''):gmatch'.' do
      t[#t+1] = c:byte()
   end
until not str
file:close()
print(#t)   --> 18330984
于 2013-05-12T11:44:16.440 に答える
0

LuaJIT を使用する場合、別の方法として、バイトのチャンクを読み取って C 配列に変換する方法があります。ファイル全体を一度に読み取る場合、バッファーはそれを格納するのに十分なメモリを割り当てる必要があります (filesize バイト)。別の方法として、ファイルをチャンクで読み取り、チャンクごとにバッファを再利用することもできます。

C バッファーを使用する利点は、バイトのチャンクを Lua 文字列または Lua テーブルに変換するよりも効率的で、メモリの観点から優れていることです。欠点は、FFI が LuaJIT でのみサポートされていることです。

local ffi = require("ffi")

-- Helper function to calculate file size.
local function filesize (fd)
   local current = fd:seek()
   local size = fd:seek("end")
   fd:seek("set", current)
   return size
end

local filename = "example.bin"

-- Open file in binary mode.
local fd, err = io.open(filename, "rb")
if err then error(err) end

-- Get size of file and allocate a buffer for the whole file.
local size = filesize(fd)
local buffer = ffi.new("uint8_t[?]", size)

-- Read whole file and store it as a C buffer.
ffi.copy(buffer, fd:read(size), size)
fd:close()

-- Iterate through buffer to print out contents.
for i=0,size-1 do
   io.write(buffer[i], " ")
end
于 2016-03-28T16:24:31.560 に答える
-1

これにより、ファイルからの各block(1)バイトfile.txtがテーブルに保存されますbytes

local bytes = {}
file = assert(io.open("file.txt","rb"))
block = 1 --blocks of 1 byte
while true do
    local byte = file:read(block)
    if byte == nil then
        break
    else
        bytes[#bytes+1] = string.byte(byte)
    end
end
file:close()
于 2013-05-12T11:18:54.890 に答える