在Python中查询块设备文件的大小
我有一个Python脚本,它可以读取一个文件(通常是从光盘上读取),并标记那些无法读取的部分,这样就可以在其他光驱上重新尝试读取这些无法读取的部分。
我发现我的脚本在处理块设备(比如/dev/sr0)时不太好用,因为它无法获取文件的大小,os.stat().st_size
返回的是零。现在我的算法需要提前知道文件的大小;我可以修改这个部分,但知道块设备大小的问题依然存在,而且这里没有人回答这个问题,所以我就提了这个问题。
我知道有两个相关的StackOverflow问题:
- 如何确定块设备的大小(/proc/partitions,使用ctypes的ioctl)
- 如何在Python中检查文件大小?(关于普通文件)
所以,我想问的是:在Python中,如何获取块设备文件的大小?
6 个回答
5
另一种可能的解决方案是
def blockdev_size(path):
"""Return device size in bytes.
"""
with open(path, 'rb') as f:
return f.seek(0, 2) or f.tell()
or f.tell()
这一部分是为了兼容Python 2,因为在Python 2中,file.seek() 返回的是None。
神奇的常量 2
可以用io.SEEK_END
来替代。
8
这是一个针对Linux系统的ioctl解决方案:
import fcntl
import struct
device_path = '/dev/sr0'
req = 0x80081272 # BLKGETSIZE64, result is bytes as unsigned 64-bit integer (uint64)
buf = b' ' * 8
fmt = 'L'
with open(device_path) as dev:
buf = fcntl.ioctl(dev.fileno(), req, buf)
bytes = struct.unpack('L', buf)[0]
print device_path, 'is about', bytes / (1024 ** 2), 'megabytes'
其他Unix系统在req、buf和fmt这些值上会有所不同。
11
我找到的“最干净”的Python解决方案(也就是说,它不依赖外部存储,并且最容易重复使用)是打开设备文件,然后移动到文件的末尾,最后返回文件的位置偏移量:
def get_file_size(filename):
"Get the file size by seeking at end"
fd= os.open(filename, os.O_RDONLY)
try:
return os.lseek(fd, 0, os.SEEK_END)
finally:
os.close(fd)