6

別の光学式リーダーで読み取り不能なセクターを再試行できるように、読み取り不能なセクターをマークするファイルを (通常は光学メディアから) 読み取る Python スクリプトがあります。

含まれている ISO9660/UDF ファイルシステムのコピーを作成するために、スクリプトがブロック デバイス (/dev/sr0 など) で動作しないことがわかりましたos.stat().st_size。アルゴリズムは現在、事前にファイルサイズを知る必要があります。それを変更することはできますが、(ブロック デバイスのサイズを知るという) 問題は残っており、ここでは回答されていないため、この質問を開きます。

私は、次の 2 つの関連する SO の質問を認識しています。

したがって、私は尋ねています: Python では、ブロックデバイスファイルのファイルサイズを取得するにはどうすればよいですか?

4

5 に答える 5

8

私が到達した「最もクリーンな」(つまり、外部ボリュームに依存せず、最も再利用可能な)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)
于 2010-05-05T14:32:30.927 に答える
7

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 の値が異なります。

于 2012-10-17T00:08:48.427 に答える
2

別の可能な解決策は

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

于 2019-07-21T21:46:23.837 に答える
0

他の答えから適応しようとしています:

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

これをテストするのに適したコンピュータが手元にありません。それが機能するかどうか知りたいです:)

于 2012-04-12T08:16:37.590 に答える