2015-10-14 92 views
0

我想創建和concat二進制文件,我需要在它們之間添加填充,由於某種原因會發生什麼是python添加垃圾並顯着增加文件(和它也改變了現有的內容)。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),那麼它會寫得很好,但如果我使用稍大一點的尺寸,它會變得非常瘋狂並且會在輸出文件中增加大量垃圾。 這段代碼並不是最優的,但對我來說並不重要,只要我能夠正確地添加填充即可。

感謝您的幫助。

更新
其實我瞭解到另一個腳本不應該改變我的文件是做什麼的,造成一個問題,由於故障。 感謝您的見解和幫助,我已經明顯改變了我的劇本。

+0

我沒有答案,但我有幾個筆記。首先,你永遠不會讀第二個文件 - 在while循環期間size被減爲零,所以'file2.read(size)'不會讀取任何內容。其次,你應該使用'with open(file)'語法 - https://docs.python.org/2/tutorial/inputoutput.html - 它將有助於更好地跟蹤你的代碼,這將有助於調試這個問題。第三,除非你需要在整個腳本中看到輸出文件的變化(而不是在最後),否則根本不需要'flush'。 – DreadPirateShawn

+0

@DreadPirateShawn我明白你的意思,我在這裏寫了泛型變量,所以大小不正確,我會解決上述問題。 –

回答

1

問題可能與您正在做的額外工作(特別是指定輸入大小)或您如何檢查輸出(上面未指定)有關。

考慮下面的,其工作方式所需的:

準備測試數據:

$ 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在這種情況下 - 有好的建議,而且往往是非常明智的,花一點額外的時間來先了解他們。

  • 例如,搜索「讀」,你會看到file.read()讀取整個文件,尺寸參數是可選。這是一個不那麼活躍的部分 - 除非你確實需要,否則不要指定大小,因爲你可能指定的不正確。

  • 在閱讀文檔時,您會看到「帶有開放式」語法推薦 - 這有助於讓代碼更易於閱讀,這通常有助於調試和維護。

  • 尋找「沖洗」,你根本找不到它,實際上 - 這是沒有必要的。谷歌的「Python刷新文件」,你會發現更詳細的確認和解釋「刷新」的用例。這是另一個移動的部分。

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

最後,總是花時間做簡單/小測試數據,就像我在這裏所做的那樣。它足夠小,您可以看到整個輸入文件和整個輸出文件,並且可以直觀地確認它們沒有損壞。此外,使用ls -l可以看到(輸出文件的大小)=(輸入1的大小)+(輸入2的大小)+填充。

現在,我們在哪裏?

這個答案提供了確認的代碼,可以實現你所說的目標。 (Yay!)誠然,你可能仍然有錯誤 - 但即使如此,現在你有一個參考點,你可以進一步調查自己的repro案例,看看它有什麼不同。 (如果它不同,請隨時發佈一個新問題,使用您自己的測試數據,完整的可運行腳本以及用於確定輸出已損壞的手段。)