如何使用二进制文件.覆盖特定字节

Sup*_*r S 1 python binaryfiles file python-3.x

我正在用python编写程序,并希望能够写入二进制文件中的特定字节.我尝试在shell中使用包含数字0到15的小二进制文件来执行此操作,但我无法弄清楚如何执行此操作.下面是我刚刚在shell中输入的代码,其中包含用于演示我要执行的操作的注释:

>>> File=open("TEST","wb") # Opens the file for writing.
>>> File.write(bytes(range(16))) # Writes the numbers 0 through 15 to the file.
16
>>> File.close() # Closes the file.
>>> File=open("TEST","rb") # Opens the file for reading, so that we can test that its contents are correct.
>>> tuple(File.read()) # Expected output: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
>>> File.close() # Closes the file.
>>> File=open("TEST","wb") # Opens the file for writing.
>>> File.seek(3) # Moves the pointer to position 3. (Fourth byte.)
3
>>> File.write(b"\x01") # Writes 1 to the file in its current position.
1
>>> File.close() # Closes the file.
>>> File=open("TEST","rb") # Opens the file for reading, so that we can test that its contents are correct.
>>> tuple(File.read()) # Expected output: (0, 1, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
(0, 0, 0, 1)
>>> File.close()
>>> File=open("TEST","wb") # I will try again using apend mode to overwrite.
>>> File.write(bytes(range(16)))
16
>>> File.close()
>>> File=open("TEST","ab") # Append mode.
>>> File.seek(3)
3
>>> File.write(b"\x01")
1
>>> File.close()
>>> File=open("TEST","rb")
>>> tuple(File.read()) # Expected output: (0, 1, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1)
>>> File.close()
Run Code Online (Sandbox Code Playgroud)

我想要的输出如图所示,但"wb"似乎擦除了文件中的所有数据,而"ab"无法向后搜索.

如何在不重写整个文件的情况下实现所需的输出?

Mar*_*ers 6

当您打开要写入w的文件时,文件将被截断,所有内容都将被删除.您需要打开文件进行读写r+.从open()功能文档:

'w' 打开写入,先截断文件

对于二进制读写访问,模式'w + b'打开并将文件截断为0字节.'r + b'打开文件而不截断.

因为文件首先被截断,寻找位置3然后写入\x01前几个字节\x00为您填写.

以附加模式打开文件通常只限制访问文件的新部分,因此任何超过前16个字节的内容.再次,从文档:

其他常见值是[...]和'a'附加(在某些Unix系统上,意味着所有写入都附加到文件的末尾,而不管当前的搜索位置).

(大胆强调引用部分我的).这就是为什么你的\x01字节最终会在最后结束,尽管有这个File.seek(3)电话.

r不会截断文件并为您提供全部内容seek(); r+添加对该模式的写访问权限.演示'r+b':

>>> with open('demo.bin', 'wb') as f:
...     f.write(bytes(range(16)))
...
16
>>> with open('demo.bin', 'rb') as f:
...     print(*f.read())
...
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
>>> with open('demo.bin', 'r+b') as f:  # read and write mode
...     f.seek(3)
...     f.write(b'\x01')
...
3
1
>>> with open('demo.bin', 'rb') as f:
...     print(*f.read())
...
0 1 2 1 4 5 6 7 8 9 10 11 12 13 14 15
Run Code Online (Sandbox Code Playgroud)