Query size of block device file in Python

Query size of block device file in Python

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 optical reader.

I discovered that my script does not work with block devices (e.g. /dev/sr0), in order to create a copy of the contained ISO9660/UDF filesystem, because os.stat().st_size is zero. The algorithm currently needs to know the filesize in advance; I can change that, but the issue (of knowing the block device size) remains, and it's not answered here, so I open this question.

I am aware of the following two related SO questions:

Therefore, I'm asking: in Python, how can I get the file size of a block device file?

Creating a new window that stays on top even when in full screen mode (Qt on Linux)


How can I figure out why cURL is hanging and unresponsive?
The “most clean” (i.e. Linux - Want To Check For Possible Duplicate Directories (Probably RegEx Needed)not dependent on external volumes and most reusable) Python quick fix I've reached, is to open the device file and seek at the end, returning the file offset:. How to track the memory usage in C++
def receive _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) 
How to completely wipe rubygems along with rails etcC functions invoked as threads - Linux userland program


How to detect pending system shutdown on Linux?
Linux-specific ioctl-based solution:. How can I setup my Netbeans IDE for making Java ME applications?
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 around ', bytes / (1024 ** 2), 'megabytes' 
Other unixes will have different values for req, buf, fmt of course..


Trying to adapt from the another 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 :).

98 out of 100 based on 78 user ratings 878 reviews