繁体   English   中英

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

[英]Query size of block device file in Python

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

我发现我的脚本不适用于块设备(例如 /dev/sr0),以便创建包含的 ISO9660/UDF 文件系统的副本,因为os.stat().st_size为零。 该算法目前需要提前知道文件大小; 我可以改变它,但问题(知道块设备大小)仍然存在,这里没有回答,所以我打开这个问题。

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

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

我已经达到的“最干净”(即不依赖于外部卷且最可重用)的 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 = 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 会有不同的值。

另一种可能的解决方案是

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 的可移植性而存在的 — file.seek()在 Python 2 中返回 None。

魔术常数2可以用io.SEEK_END

在 Linux 中,即使没有 sudo 也可以读取/sys/block/${dev}/size 要获取/dev/sdb的大小,只需执行以下操作:

print( 512 * int(open('/sys/block/sdb/size','r').read()) )

另见https://unix.stackexchange.com/a/52219/384116

试图适应另一个答案:

import fcntl
c = 0x00001260 ## check man ioctl_list, BLKGETSIZE
f = open('/dev/sr0', 'ro')
s = fcntl.ioctl(f, c)
print s

我手头没有合适的计算机来测试这个。 我很想知道它是否有效:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM