关于Linux:python中块设备文件的查询大小

Query size of block device file in Python

我有一个python脚本,它读取一个标记不可读扇区的文件(通常是从光学媒体读取的),以允许在不同的光学阅读器上重新尝试读取所说的不可读扇区。

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

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

  • 确定块设备的大小(/proc/partitions,ioctl到ctypes)
  • 如何在python中检查文件大小?(关于非特殊文件)

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


我所达到的"最干净"(即不依赖外部卷和最可重用)的python解决方案是打开设备文件并在末尾查找,返回文件偏移量:

1
2
3
4
5
6
7
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解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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'

当然,其他unixes对于req、buf和fmt的值也不同。


尝试从另一个答案中适应:

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

我手头没有合适的电脑来测试这个。我很想知道它是否有效。)