Python - appending/padding 二进制文件添加垃圾

Python - appending/padding binary file adds garbage

我正在尝试创建和连接二进制文件,我需要在它们之间添加填充,由于某种原因发生的事情是 python 添加了垃圾并显着增加了文件(并且它也改变了现有内容)。

我做的是这样的

file1 = OPEN(read_file, "rb")
file2 = OPEN(read_file, "rb")
file3 = OPEN(write_file, "ab")
data = file1.read(f1_size)
file3.write(data)
file3.flush()
file1.close()
while padding_size > 0:
   file3.write(b'\x00')
   padding_size -= 1
   file3.flush() # Not sure this is mandatory here
data2 = file2.read(f2_size)
file3.write(data2)
file3.flush()
file2.close()
file3.close()

这甚至发生在我添加第二个二进制文件之前。如果我使用较小的尺寸(比如 100),那么它写得很好,但如果我使用稍大的尺寸,它就会变得疯狂并向输出文件添加大量垃圾。 这段代码不是最优的,但对我来说并不重要,只要我能够正确添加填充即可。

感谢您的帮助。

Update
我实际上了解到另一个 不应该更改我的文件 的脚本正在执行它并导致由于失败而引起的问题。 感谢您的见解和帮助,我对脚本进行了重大更改。

问题可能与您正在做的额外工作(特别是指定输入大小)或您检查输出的方式有关(上面未指定)。

考虑以下内容,它按预期工作:

准备测试数据:

$ echo "abc" > input1
$ echo "def" > input2
$ zip input1.zip input1
  adding: input1 (stored 0%)
$ zip input2.zip input2
  adding: input2 (stored 0%)
$ cat -v input1.zip
PK^C^D
^@^@^@^@^@)}NGNM-^AM-^HG^D^@^@^@^D^@^@^@^F^@^\^@input1UT    ^@^CM-^^w^^V[x^^Vux^K^@^A^DM-]^E^@^@^DM-]^E^@^@abc
PK^A^B^^^C
^@^@^@^@^@)}NGNM-^AM-^HG^D^@^@^@^D^@^@^@^F^@^X^@^@^@^@^@^A^@^@^@M-$M-^A^@^@^@^@input1UT^E^@^CM-^^w^^Vux^K^@^A^DM-]^E^@^@^DM-]^E^@^@PK^E^F^@^@^@^@^A^@^A^@L^@^@^@D^@^@^@^@^@
$ cat -v input2.zip
PK^C^D
^@^@^@^@^@.}NGM-<M-^Sn^H^D^@^@^@^D^@^@^@^F^@^\^@input2UT    ^@^CM-'w^^V[x^^Vux^K^@^A^DM-]^E^@^@^DM-]^E^@^@def
PK^A^B^^^C
^@^@^@^@^@.}NGM-<M-^Sn^H^D^@^@^@^D^@^@^@^F^@^X^@^@^@^@^@^A^@^@^@M-$M-^A^@^@^@^@input2UT^E^@^CM-'w^^Vux^K^@^A^DM-]^E^@^@^DM-]^E^@^@PK^E^F^@^@^@^@^A^@^A^@L^@^@^@D^@^@^@^@^@

精简脚本"test.py":

read_file1 = "input1.zip"
read_file2 = "input2.zip"
write_file = "output"
padding_size = 50

with open(write_file, "ab") as file3:
    with open(read_file1, "rb") as file1:
        data = file1.read()
        file3.write(data)
    while padding_size > 0:
        file3.write(b'\x00')
        padding_size -= 1
    with open(read_file2, "rb") as file2:
        data = file2.read()
        file3.write(data)

输出:

$ python test.py
$ cat -v output
PK^C^D
^@^@^@^@^@)}NGNM-^AM-^HG^D^@^@^@^D^@^@^@^F^@^\^@input1UT    ^@^CM-^^w^^V[x^^Vux^K^@^A^DM-]^E^@^@^DM-]^E^@^@abc
PK^A^B^^^C
^@^@^@^@^@)}NGNM-^AM-^HG^D^@^@^@^D^@^@^@^F^@^X^@^@^@^@^@^A^@^@^@M-$M-^A^@^@^@^@input1UT^E^@^CM-^^w^^Vux^K^@^A^DM-]^E^@^@^DM-]^E^@^@PK^E^F^@^@^@^@^A^@^A^@L^@^@^@D^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@PK^C^D
^@^@^@^@^@.}NGM-<M-^Sn^H^D^@^@^@^D^@^@^@^F^@^\^@input2UT    ^@^CM-'w^^V[x^^Vux^K^@^A^DM-]^E^@^@^DM-]^E^@^@def
PK^A^B^^^C
^@^@^@^@^@.}NGM-<M-^Sn^H^D^@^@^@^D^@^@^@^F^@^X^@^@^@^@^@^A^@^@^@M-$M-^A^@^@^@^@input2UT^E^@^CM-'w^^Vux^K^@^A^DM-]^E^@^@^DM-]^E^@^@PK^E^F^@^@^@^@^A^@^A^@L^@^@^@D^@^@^@^@^@
$ ls -l
total 24
-rw-r--r-- 1 foo bar   4 Oct 14 15:41 input1
-rw-r--r-- 1 foo bar 166 Oct 14 15:45 input1.zip
-rw-r--r-- 1 foo bar   4 Oct 14 15:41 input2
-rw-r--r-- 1 foo bar 166 Oct 14 15:45 input2.zip
-rw-r--r-- 1 foo bar 382 Oct 14 15:58 output
-rw-r--r-- 1 foo bar 406 Oct 14 15:58 test.py

备注:

文档 - https://docs.python.org/2/tutorial/inputoutput.html 在这种情况下 - 有很好的建议,通常花一些额外的时间先理解它们是非常明智的。

  • 例如,搜索"read",您会看到file.read()读取整个文件,大小参数是可选的。那是一个不太移动的部分——除非你真的必须,否则不要指定大小,因为你可能会错误地指定它。

  • 在阅读文档时,您会看到推荐的 "with open" 语法——这有助于使代码更易于阅读,这通常有助于调试和维护。

  • 搜索 "flush" 并且您根本找不到,实际上 - 没有必要。 Google "Python flush file" 并且您会找到关于 "flush" 的用例的更详细的确认和解释。这是另一个需要删除的移动部分。

因此我修改了上面的代码。

最后,总是花时间制作简单/小的测试数据,就像我在这里所做的那样。它足够小,您可以看到整个输入文件和整个生成的输出文件,并且可以直观地确认它们没有损坏。此外,使用 ls -l 您可以看到(输出文件的大小)=(输入 1 的大小)+(输入 2 的大小)+ 填充。

现在,我们将何去何从?

此答案提供了可实现您既定目标的确认代码。 (耶!)诚然,您可能仍然有错误——但即使如此,现在您也有一个参考点,您可以使用它来进一步调查您自己的重现案例,看看它有何不同。 (如果确实不同,请随时 post 一个新问题,使用您自己的测试数据、完整的可运行脚本以及您用来确定输出是否已损坏的方法。)