在Python中查询块设备文件的大小

8 投票
6 回答
7983 浏览
提问于 2025-04-15 22:23

我有一个Python脚本,它可以读取一个文件(通常是从光盘上读取),并标记那些无法读取的部分,这样就可以在其他光驱上重新尝试读取这些无法读取的部分。

我发现我的脚本在处理块设备(比如/dev/sr0)时不太好用,因为它无法获取文件的大小,os.stat().st_size返回的是零。现在我的算法需要提前知道文件的大小;我可以修改这个部分,但知道块设备大小的问题依然存在,而且这里没有人回答这个问题,所以我就提了这个问题。

我知道有两个相关的StackOverflow问题:

所以,我想问的是:在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)

撰写回答