Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用二进制文件。覆盖特定字节_Python_Python 3.x_File_Binaryfiles - Fatal编程技术网

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

Python 如何使用二进制文件。覆盖特定字节,python,python-3.x,file,binaryfiles,Python,Python 3.x,File,Binaryfiles,我正在用python编写一个程序,希望能够在二进制文件中写入特定的字节。我试图在shell中使用一个包含数字0到15的小二进制文件来实现这一点,但我不知道如何实现。下面是我刚刚在shell中输入的带有注释的代码,以演示我正在尝试执行的操作: >>> File=open("TEST","wb") # Opens the file for writing. >>> File.write(bytes(range(16))) # Writes the numbers

我正在用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()
我想要的输出如图所示,但wb似乎删除了文件中的所有数据,而ab无法向后搜索


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

当您使用w打开文件进行写入时,文件将被截断,所有内容都将被删除。您需要使用r+打开文件进行读写。从open function文档中:

“w”打开以进行写入,首先截断文件

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

由于文件首先被截断,因此在查找位置3然后写入\x01时,会在前几个字节中填入\x00

在附加模式下打开文件通常只会限制对文件新部分的访问,因此任何超过前16个字节的内容都会受到限制。同样,从文档中:

其他常用值是[…]和“a”,用于附加,在某些Unix系统上,这意味着所有写入操作都附加到文件的末尾,而不管当前查找位置如何

引用章节中的粗体强调。这就是为什么尽管调用了File.seek3,您的\x01字节仍在末尾

r不会截断文件,并通过seek提供完整的内容范围;r+将写入权限添加到该模式。带“r+b”的演示:


当您使用w打开一个文件进行写入时,该文件将被截断,所有内容都将被删除。您需要使用r+打开文件进行读写。从open function文档中:

“w”打开以进行写入,首先截断文件

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

由于文件首先被截断,因此在查找位置3然后写入\x01时,会在前几个字节中填入\x00

在附加模式下打开文件通常只会限制对文件新部分的访问,因此任何超过前16个字节的内容都会受到限制。同样,从文档中:

其他常用值是[…]和“a”,用于附加,在某些Unix系统上,这意味着所有写入操作都附加到文件的末尾,而不管当前查找位置如何

引用章节中的粗体强调。这就是为什么尽管调用了File.seek3,您的\x01字节仍在末尾

r不会截断文件,并通过seek提供完整的内容范围;r+将写入权限添加到该模式。带“r+b”的演示:


如果我没记错的话,你必须在附加模式下打开文件,否则它只会删除所有内容,从头开始,然后当你使用seek3时,你只需要创建那些3 0,然后写1。我将进一步研究如何直接写入某个位置,但您可能需要读取整个文件,修改,再写入整个文件

您可以在以下内容中了解这种行为:

仅用于写入具有相同名称的现有文件的“w”将被擦除


如果我没记错的话,你必须在附加模式下打开文件,否则它只会删除所有内容,从头开始,然后当你使用seek3时,你只需要创建那些3 0,然后写1。我将进一步研究如何直接写入某个位置,但您可能需要读取整个文件,修改,再写入整个文件

您可以在以下内容中了解这种行为:

仅用于写入具有相同名称的现有文件的“w”将被擦除


解决方案是另一种模式:r+b。如其他答案所示

以下是shell中的解决方案,该文件从中删除:

>>> File=open("TEST","r+b") # Opens file for reading and writing.
>>> 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, 1)
(0, 1, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1)
>>> File.close()

解决方案是另一种模式:r+b。如其他答案所示

以下是shell中的解决方案,该文件从中删除:

>>> File=open("TEST","r+b") # Opens file for reading and writing.
>>> 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, 1)
(0, 1, 2, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1)
>>> File.close()

在我的问题中,我已经说明了追加模式在这种情况下不起作用。或者更确切地说,追加模式确实起作用——它强制执行写入操作,直到结束。它并不是专门用来修改现有内容的。是的,也许我写得有点太快了,因为我不得不去参加一个会议,但我并不打算让附加模式成为你的解决方案:Martijin在解释如何解决你的问题方面做得更好。我在我的问题中表明,附加模式在这种情况下不起作用。或者更确切地说,这种追加模式确实有效——它强制执行写入到末尾。它并不是专门用来修改现有内容的。是的,也许我写得有点太快了,因为我不得不去参加一个会议,但我并不打算把附加模式作为你的解决方案:Martijin在解释如何解决你的问题方面做得更好 问题