Query size of block device file in Python

后端 未结 4 1181
南笙
南笙 2021-01-05 22:53

I have a Python script that reads a file (typically from optical media) marking the unreadable sectors, to allow a re-attempt to read said unreadable sectors on a different

相关标签:
4条回答
  • 2021-01-05 23:23

    Another possible solution is

    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() part is there for Python 2 portability's sake — file.seek() returns None in Python 2.

    Magic constant 2 may be substituted with io.SEEK_END.

    0 讨论(0)
  • 2021-01-05 23:30

    Linux-specific ioctl-based solution:

    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'
    

    Other unixes will have different values for req, buf, fmt of course.

    0 讨论(0)
  • 2021-01-05 23:30

    Trying to adapt from the other answer:

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

    I don't have a suitable computer at hand to test this. I'd be curious to know if it works :)

    0 讨论(0)
  • 2021-01-05 23:47

    The “most clean” (i.e. not dependent on external volumes and most reusable) Python solution I've reached, is to open the device file and seek at the end, returning the file offset:

    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)
    
    0 讨论(0)
提交回复
热议问题