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

2024-06-14 09:54:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python脚本,它读取一个标记不可读扇区的文件(通常是从光学介质读取的),以允许在不同的光学读取器上重新尝试读取上述不可读扇区。

我发现,为了创建所包含的ISO9660/UDF文件系统的副本,我的脚本不能与块设备(例如/dev/sr0)一起工作,因为os.stat().st_size为零。算法目前需要预先知道文件大小;我可以更改它,但是(知道块设备大小)问题仍然存在,这里没有回答,所以我打开了这个问题。

我知道以下两个相关的SO问题:

因此,我要问:在Python中,如何获得块设备文件的文件大小?


Tags: 文件标记dev脚本sizeos副本读取器
3条回答

另一个可能的解决方案是

def blockdev_size(path):
    """Return device size in bytes.
    """
    with open(path, 'rb') as f:
        return f.seek(0, 2) or f.tell()

为了Python 2的可移植性,or f.tell()部分存在-file.seek()在python2中不返回任何内容。

魔法常数2可以用^{}替换。

我找到的“最干净”(即不依赖外部卷和最可重用)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)

基于Linux特定ioctl的解决方案:

import fcntl
import struct

device_path = '/dev/sr0'

req = 0x80081272 # BLKGETSIZE64, result is bytes as unsigned 64-bit integer (uint64)
buf = ' ' * 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有不同的值。

相关问题 更多 >