質問から、コードで改善すべきことがいくつかわかります。まず、ループを使用するか、いくつかの組み込み関数をwhile
使用して同じことを表現するより良い方法がほとんどの場合、Python でループが使用されることはめったにありません。for
コードは純粋にトレーニング目的かそうです。それ以外の場合は、最初に本当の目標は何かを尋ねます (問題を知っているため、より良い解決策は最初のアイデアとは大きく異なる可能性があるため)。
ここでの目標は、 の位置を取得することseek
です。あなたはサイズを知っています、あなたはチャンクサイズを知っています、あなたは逆に行きたいです. という名前の Python の目的のための組み込みジェネレーターがありrange
ます。ほとんどの場合、単一の引数が使用されます。ただし、range(start, stop, step)
完全な形式です。ジェネレーターはfor
ループ内で繰り返すことができます。また、値を使用してそれらのリストを作成することもできます (ただし、後者のケースは必要ないことがよくあります)。の位置は次のseek
ように生成できます。
chunk = 10
sz = 235
lst = list(range(sz - chunk, 0, -chunk))
print(lst)
sz - chunk
つまり、次の生成値に負の値を使用して、位置から開始し、ゼロで停止します (頻繁ではありません)。ここで はlist()
すべての値を繰り返し処理し、それらのリストを作成します。ただし、生成された値を直接反復処理できます。
for pos in range(sz - chunk, 0, -chunk):
print('seek({}) and read({})'.format(pos, chunk))
if pos > 0:
print('seek({}) and read({})'.format(0, pos))
最後に生成された位置は、ゼロまたは正です。このように、 lastif
は より短い最後の部分を処理しchunk
ます。上記のコードをまとめると、次のように出力されます。
c:\tmp\_Python\wikicsm\so16443185>py a.py
[225, 215, 205, 195, 185, 175, 165, 155, 145, 135, 125, 115, 105, 95,
85, 75, 65, 55, 45, 35, 25, 15, 5]
seek(225) and read(10)
seek(215) and read(10)
seek(205) and read(10)
seek(195) and read(10)
seek(185) and read(10)
seek(175) and read(10)
seek(165) and read(10)
seek(155) and read(10)
seek(145) and read(10)
seek(135) and read(10)
seek(125) and read(10)
seek(115) and read(10)
seek(105) and read(10)
seek(95) and read(10)
seek(85) and read(10)
seek(75) and read(10)
seek(65) and read(10)
seek(55) and read(10)
seek(45) and read(10)
seek(35) and read(10)
seek(25) and read(10)
seek(15) and read(10)
seek(5) and read(10)
seek(0) and read(5)
print
私は個人的に、ファイル オブジェクト、pos、およびチャンク サイズを取得する関数を呼び出して、's を置き換えます。ここでは、同じプリントを生成するための偽造されたボディ:
#!python3
import os
def processChunk(f, pos, chunk_size):
print('faked f: seek({}) and read({})'.format(pos, chunk_size))
fname = 'a.txt'
sz = os.path.getsize(fname) # not checking existence for simplicity
chunk = 16
with open(fname, 'rb') as f:
for pos in range(sz - chunk, 0, -chunk):
processChunk(f, pos, chunk)
if pos > 0:
processChunk(f, 0, pos)
with
コンストラクトは、学ぶのに適したもう 1 つの要素です。(警告、Pascal の に似たものは何もありませんwith
。) ブロックが終了した後、ファイル オブジェクトを自動的に閉じます。以下のコードwith
はより読みやすく、今後変更する必要がないことに注意してください。はprocessChunk
さらに開発されます。
def processChunk(f, pos, chunk_size):
f.seek(pos)
s = binascii.hexlify(f.read(chunk_size))
print(s)
または、結果が逆の 16 進ダンプ (私のコンピューターでテストされた完全なコード) になるように、少し変更することもできます。
#!python3
import binascii
import os
def processChunk(f, pos, chunk_size):
f.seek(pos)
b = f.read(chunk_size)
b1 = b[:8] # first 8 bytes
b2 = b[8:] # the rest
s1 = ' '.join('{:02x}'.format(x) for x in b1)
s2 = ' '.join('{:02x}'.format(x) for x in b2)
print('{:08x}:'.format(pos), s1, '|', s2)
fname = 'a.txt'
sz = os.path.getsize(fname) # not checking existence for simplicity
chunk = 16
with open(fname, 'rb') as f:
for pos in range(sz - chunk, 0, -chunk):
processChunk(f, pos, chunk)
if pos > 0:
processChunk(f, 0, pos)
a.txt
が最後のコードのコピーである場合、以下が生成されます。
c:\tmp\_Python\wikicsm\so16443185>py d.py
00000274: 75 6e 6b 28 66 2c 20 30 | 2c 20 70 6f 73 29 0d 0a
00000264: 20 20 20 20 20 20 20 70 | 72 6f 63 65 73 73 43 68
00000254: 20 20 69 66 20 70 6f 73 | 20 3e 20 30 3a 0d 0a 20
00000244: 6f 73 2c 20 63 68 75 6e | 6b 29 0d 0a 0d 0a 20 20
00000234: 72 6f 63 65 73 73 43 68 | 75 6e 6b 28 66 2c 20 70
00000224: 75 6e 6b 29 3a 0d 0a 20 | 20 20 20 20 20 20 20 70
00000214: 20 2d 20 63 68 75 6e 6b | 2c 20 30 2c 20 2d 63 68
00000204: 20 70 6f 73 20 69 6e 20 | 72 61 6e 67 65 28 73 7a
000001f4: 61 73 20 66 3a 0d 0a 0d | 0a 20 20 20 20 66 6f 72
000001e4: 65 6e 28 66 6e 61 6d 65 | 2c 20 27 72 62 27 29 20
000001d4: 20 3d 20 31 36 0d 0a 0d | 0a 77 69 74 68 20 6f 70
000001c4: 69 6d 70 6c 69 63 69 74 | 79 0d 0a 63 68 75 6e 6b
000001b4: 20 65 78 69 73 74 65 6e | 63 65 20 66 6f 72 20 73
000001a4: 20 20 23 20 6e 6f 74 20 | 63 68 65 63 6b 69 6e 67
00000194: 65 74 73 69 7a 65 28 66 | 6e 61 6d 65 29 20 20 20
00000184: 0d 0a 73 7a 20 3d 20 6f | 73 2e 70 61 74 68 2e 67
00000174: 0a 66 6e 61 6d 65 20 3d | 20 27 61 2e 74 78 74 27
00000164: 31 2c 20 27 7c 27 2c 20 | 73 32 29 0d 0a 0d 0a 0d
00000154: 27 2e 66 6f 72 6d 61 74 | 28 70 6f 73 29 2c 20 73
00000144: 20 20 70 72 69 6e 74 28 | 27 7b 3a 30 38 78 7d 3a
00000134: 66 6f 72 20 78 20 69 6e | 20 62 32 29 0d 0a 20 20
00000124: 30 32 78 7d 27 2e 66 6f | 72 6d 61 74 28 78 29 20
00000114: 32 20 3d 20 27 20 27 2e | 6a 6f 69 6e 28 27 7b 3a
00000104: 20 78 20 69 6e 20 62 31 | 29 0d 0a 20 20 20 20 73
000000f4: 7d 27 2e 66 6f 72 6d 61 | 74 28 78 29 20 66 6f 72
000000e4: 20 27 20 27 2e 6a 6f 69 | 6e 28 27 7b 3a 30 32 78
000000d4: 65 20 72 65 73 74 0d 0a | 20 20 20 20 73 31 20 3d
000000c4: 20 20 20 20 20 20 20 20 | 20 20 20 20 23 20 74 68
000000b4: 62 32 20 3d 20 62 5b 38 | 3a 5d 20 20 20 20 20 20
000000a4: 73 74 20 38 20 62 79 74 | 65 73 0d 0a 20 20 20 20
00000094: 20 20 20 20 20 20 20 20 | 20 20 20 23 20 66 69 72
00000084: 31 20 3d 20 62 5b 3a 38 | 5d 20 20 20 20 20 20 20
00000074: 75 6e 6b 5f 73 69 7a 65 | 29 0d 0a 20 20 20 20 62
00000064: 20 20 20 62 20 3d 20 66 | 2e 72 65 61 64 28 63 68
00000054: 20 20 66 2e 73 65 65 6b | 28 70 6f 73 29 0d 0a 20
00000044: 63 68 75 6e 6b 5f 73 69 | 7a 65 29 3a 0d 0a 20 20
00000034: 73 73 43 68 75 6e 6b 28 | 66 2c 20 70 6f 73 2c 20
00000024: 20 6f 73 0d 0a 0d 0a 64 | 65 66 20 70 72 6f 63 65
00000014: 62 69 6e 61 73 63 69 69 | 0d 0a 69 6d 70 6f 72 74
00000004: 74 68 6f 6e 33 0d 0a 0d | 0a 69 6d 70 6f 72 74 20
00000000: 23 21 70 79 |
の場合、Windowssrc_file_path = 'd:\\src\\python\\test\\main.zip'
と同様にスラッシュを使用できます。または、src_file_path = r'd:\src\python\test\main.zip' のような生の文字列src_file_path = 'd:/src/python/test/main.zip'
を使用できます。最後のケースは、バックスラッシュを二重にするのを避ける必要がある場合に使用されます -- 多くの場合、正規表現を書く場合です。