从这个问题中我可以看出代码中有几点需要改进。首先,while循环在Python中很少使用,因为使用for循环或使用一些内置函数几乎总是有更好的方法来表达相同的内容。在
我想代码纯粹是为了培训目的。否则,我会首先问真正的目标是什么(因为知道了问题,更好的解决方案可能与第一个想法大不相同)。在
这里的目标是获得seek的位置。你知道大小,你知道块大小,你想倒退。Python中有一个内置的生成器,名为range。通常使用单个参数;但是,range(start, stop, step)是完整形式。生成器可以在for循环中迭代,也可以使用say值构建它们的列表(但通常不需要后面的情况)。seek的位置可以这样生成:chunk = 10
sz = 235
lst = list(range(sz - chunk, 0, -chunk))
print(lst)
也就是说,从sz - chunk位置开始,在零处停止(不经常),使用下一个生成值的负值。在这里,list()遍历所有值并构建它们的列表。但可以直接迭代生成的值:
^{pr2}$
最后生成的位置是或零或正。这样,当最后一个if比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)
我个人会通过调用接受file对象pos和块大小的函数来替换print。在这里伪造的尸体产生了相同的指纹:#!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结构是另一个值得学习的结构。(警告,与Pascal的with)它在块结束后自动关闭file对象。请注意,with下面的代码更具可读性,以后不需要更改。将进一步开发processChunk:def processChunk(f, pos, chunk_size):
f.seek(pos)
s = binascii.hexlify(f.read(chunk_size))
print(s)
或者您可以稍微更改它,使其结果是一个反向hextump(在我的计算机上测试的完整代码):#!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 |
对于src_file_path = 'd:\\src\\python\\test\\main.zip',也可以在Windows中使用类似src_file_path = 'd:/src/python/test/main.zip'的正斜杠。或者您可以使用原始字符串,比如src_file_path=r'd:\src\python\test\主.zip'. 最后一种情况是当您需要避免在编写常规表达式时经常使用反斜杠。在