我正在使用Lua脚本来确定文件大小:
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
但是,这似乎只适用于高达2GB的文件。 对于较大的文件,文件filesize
始终nil
。 io.open
有没有限制? 如果是这样,我怎么能解决这个问题呢?
在Windows Server 2008 R2 64bit上运行Lua 5.1.4
问题不在io.open
,而是file:seek
。 你可以检查这样的错误:
filesize, err = file:seek("end") if not filesize then print(err) end
错误消息可能是Invalid argument
。 这是因为对于大于2GB的文件,其大小超过了32位long
容量,导致C函数fseek
失效。
在POSIX系统中,Lua使用fseeko
,而不是fseek
fseeko
的大小。 在Windows中,有一个_fseeki64
,我猜也是类似的工作。 如果这些不可用,则使用fseek
,这会导致问题。
相关来源是liolib.c
(Lua 5.2)。 正如@lhf指出的那样,在Lua 5.1中, fseek
总是被使用( 来源 )。 升级到Lua 5.2可能可以解决这个问题。
在内部,Lua使用ISO C函数long int ftell(FILE *stream);
确定file:seek()
的返回值。 long int
在Windows上总是32位,所以你在这里运气不好。 如果可以的话,你应该使用一些外部库来检测文件大小 – 我推荐luafilesystem 。
在旧的Lua版本(其中file:seek()
被限制为2Gb),您可以要求cmd.exe
获取文件大小:
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