2014-11-05 10 views
6

Ich bin ein Lua-Skript um die Dateigröße zu bestimmen:Lua - io.open() nur bis zu 2 GB?

local filesize=0 
local filePath = "somepath.bin" 
local file,msg = io.open(filePath, "r") 
if file then 
    filesize=file:seek("end") 
    file:close() 
    filePresent = true 
end 

Doch diese scheinen nur für Dateien bis zu 2 GB zu arbeiten. Für größere Dateien ist filesize immer nil. Gibt es Einschränkungen bezüglich io.open? Und wenn ja, wie könnte ich das umgehen?

Lauf Lua 5.1.4 auf Windows Server 2008 R2 64bit

+2

Btw, sollten Sie Binär-Dateien öffnen mit '„rb“' statt '" r "'. – siffiejoe

+0

Ist ein Upgrade auf Lua 5.2 möglich? – lhf

+0

Da die Lua tatsächlich eingebettet ist, denke ich nicht, dass ich leicht upgraden könnte :(Wäre 5.2 das Problem lösen? – silent

Antwort

3

Intern verwendet Lua die ISO-C-Funktion long int ftell(FILE *stream); den Rückgabewert für file:seek() zu bestimmen. A long int ist immer 32 Bit unter Windows, so dass Sie hier kein Glück haben. Wenn Sie können, sollten Sie eine externe Bibliothek verwenden, um die Dateigröße zu erkennen - ich empfehle luafilesystem.

5

Das Problem ist nicht in io.open, aber file:seek. Sie können den Fehler wie folgt überprüfen:

filesize, err = file:seek("end") 
if not filesize then 
    print(err) 
end 

Die Fehlermeldung ist wahrscheinlich Invalid argument. Das liegt daran, dass die Größe von Dateien mit mehr als 2 GB größer ist als 32-Bit long, wodurch die C-Funktion fseek nicht funktioniert.

In POSIX-Systemen verwendet Lua fseeko, die die Größe von off_t statt long in fseek nimmt. In Windows gibt es eine _fseeki64, die ich denke, macht ähnliche Arbeit. Wenn diese nicht verfügbar sind, wird fseek verwendet, und es würde das Problem verursachen.


Die relevante Quelle ist liolib.c (LUA 5.2). Wie @lhf zeigt, wird in Lua 5.1 immer fseek verwendet (source). Ein Upgrade auf Lua 5.2 könnte das Problem möglicherweise lösen.

+1

Aber Sie können immer noch lesen/schreiben Daten größer als 2G. Ich las 9G-Datei auf Win2k3 (x32). Sie können nur nicht 'suchen' – moteus

+0

Leider verwendet Lua 5.1' fseek' nur und versucht nicht, 'fseeko' zu verwenden. – lhf

+0

Ja, richtig, ich bekomme das ungültige Argument. Also ist die einzige Option, eine andere Bibliothek zu verwenden ?! – silent

0

Auf alten Lua-Versionen (wo file:seek() auf 2 GB beschränkt ist) Sie cmd.exe fragen kann die Dateigröße zu erhalten.

function filesize(filename) 
    -- returns file size (or nil if the file doesn't exist or unable to open) 
    local command = 'cmd /d/c for %f in ("'..filename..'") do @echo(%~zf' 
    return tonumber(io.popen(command):read'*a') 
end 

print(filesize[[C:\Program Files\Windows Media Player\wmplayer.exe]]) 
     --> 73728 
print(filesize[[E:\City.of.the.Living.Dead.1980.720p.BluRay.x264.Skazhutin.mkv]]) 
     --> 8505168882 
Verwandte Themen