2013-12-18 80 views
5

以下是我的問題重新措辭Python的讀取和寫入到二進制文件

讀前10個字節的二進制文件(操作後) -

infile = open('infile.jpg', 'rb') 
outfile = open('outfile.jpg', 'wb') 
x = infile.read(10) 
for i in x: 
    print(i, end=', ') 
print(x) 
outfile.write(bytes(x, "UTF-8")) 

第一個print語句讓 -

255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 

第二打印語句使 -

b'\xff\xd8\xff\xe0\x00\x10JFIF' 

x的值的十六進制解釋。

outfile.write(bytes(x, "UTF-8")) 

回報 -

​​

那麼x不能是普通的字符串,而是一個字節串,這仍然是迭代?

如果我想寫x的內容outfile.jpg不變的話,我去 -

outfile.write(x) 

現在我試圖把每個x [i]和執行上的每個部分的操作(如下圖所示爲1)的簡單骨骼產品,將值賦給y並將y寫入outfile.jpg,使其與infile.jpg相同。所以我嘗試 -

infile = open('infile.jpg', 'rb') 
outfile = open('outfile.jpg', 'wb') 
x = infile.read(10) 

yi = len(x) 
y = [0 for i in range(yi)] 

j = 0 
for i in x: 
    y [j] = i*1 
    j += 1 

for i in x: 
    print(i, end=', ') 

print(x) 

for i in y: 
    print(i, end=', ') 

print(y) 

print(repr(x)) 
print(repr(y)) 

outfile.write(y) 

第一個print語句(通過X迭代)讓 -

255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 

第二打印語句使 -

b'\xff\xd8\xff\xe0\x00\x10JFIF' 

第三個print語句(至Y迭代)給出 -

255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 

print語句給人 -

[255, 216, 255, 224, 0, 16, 74, 70, 73, 70] 

最後,印刷再版(x)和再版(Y),由Tim的建議,給了分別 -

b'\xff\xd8\xff\xe0\x00\x10JFIF' 
[255, 216, 255, 224, 0, 16, 74, 70, 73, 70] 

和文件寫入聲明爲錯誤 -

TypeError: 'list' does not support the buffer interface 

我需要的是y以具有相同的類型爲x使得outfile.write(X)= outfile.write(Y)

我盯着Python的眼睛,但我仍然沒有看到它的靈魂。

+0

看看這篇文章:http://stackoverflow.com/questions/5471158/typeerror-str-does-not-support-the-buffer-interface似乎是在Python 2和Python 3之間改變了String類。 –

+0

Hunter - 我用outfile.write(s.encode('UTF-8')替換了outfile.write(s)並且沒有收到任何錯誤!但是使用infile.read()導致outfile.jpg的大小是infile的兩倍。 jpg和破壞我想要完成的是讀取二進制文件,執行操作,反轉該操作並將輸出寫入單獨的文件以使它們完全相同 – brett

+0

在後面的答案中,我鏈接了使用的'outfile.write (bytes(s,「UTF-8」));' –

回答

3

他們完全不一樣 - 他們只是顯示str()適用於他們(其中print()含蓄地)後相同。打印repr()他們,你會看到不同之處。例如:

>>> x = b'ab' 
>>> y = "b'ab'" 
>>> print(x) 
b'ab' 
>>> print(y) # displays identically 
b'ab' 
>>> print(repr(x)) # but x is really a 2-byte bytes object 
b'ab' 
>>> print(repr(y)) # and y is really a 5-character string 
"b'ab'" 

混合字符串和字節對象是沒有意義的(當然,不是在沒有明確的編碼 - 但你不是試圖來編碼/解碼這裏什麼,對吧?)。如果你使用二進制文件,那麼你根本不應該使用字符串 - 你應該使用bytesbytearray對象。

所以這個問題並不是真的在你的寫作方式上:邏輯在此之前基本上是混淆的。

無法猜出你想要的。請編輯該問題,以顯示您正在嘗試完成的的完整可執行示例。我們不需要JPG文件 - 編寫一些簡短的任意二進制數據。像:

dummy_jpg = b'\x01\x02\xff' 
+0

哇,repr()表明有區別,我將不得不重新思考我正在嘗試做什麼的邏輯。 – brett

1

......這是你如何閱讀和以二進制方式寫入文件Python編寫的。

#open binary files infile and outfile 
infile = open('infile.jpg', 'rb') 
outfile = open('outfile.jpg', 'wb') 

#n = bytes to read 
n=5 

#read bytes of infile to x 
x = infile.read(n) 

#print x type, x 
print() 
print('x = ', repr(x), type(x)) 
print() 

X = B '\ XFF \ XD8 \ XFF \ xe0 \ X00' 類 '字節'

#define y of type list, lenth xi, type list 
xi = len(x) 
y = [0 for i in range(xi)] 

#print y type, y 
print('y =', repr(y), type(y)) 
print() 

Y = [0,0,0,0,0]類的列表'

#convert x to 8 bit octals and place in y, type list 
j=0 
for i in x: 
    y [j] = '{:08b}' .format(ord(i)) 
    j += 1 

#print y type, and y 
print('y =', repr(y), type(y)) 
print() 

Y = [' 11111111' , '11011000', '11111111', '11100000', '00000000']類名單'

#perform bit level operations on y [i], not done in this example. 

#convert y [i] back to integer 
j=0 
for i in y: 
    y [j] = int(i, 2) 
    j += 1 

#print y type, and y 
print('y =', repr(y), type(y)) 
print() 

Y = [255,216,255,224,0]類名單'

#convert y to type byte and place in z 
z = bytearray(y) 

#print z type, and z 
print('z =', repr(z), type(z)) 
print() 

Z =字節組(B '\ XFF \ XD8 \ XFF \ xe0 \ X00')類的字節組'

#output z to outfile 
outfile.write(z) 

infile.close() 
outfile.close() 
outfile = open('outfile.jpg', 'rb') 

#read bytes of outfile to x 
x = outfile.read(n) 

#print x type, and x 
print('x =', repr(x), type(x)) 
print() 

X = b '\ XFF \ XD8 \ XFF \ xe0 \ X00' 類 '字節'

#conclusion: first n bytes of infile = n bytes of outfile (without bit level operations) 

outfile.close() 
0

感謝澄清!您想要的內容非常簡單,但您確實需要閱讀bytesbytearray類型的文檔。你切勿需要的是具有做任何事情:

  • 統一
  • 編碼
  • 解碼

這些都是完全不相關的在這裏。您從開始到結束都有二進制數據,並且需要堅持使用bytes和/或bytearray對象。兩者都是字節序列(range(256)中的「小整數」); bytes是一個不可變的序列,而bytearray是一個可變序列。

那麼x不能是一個正常的字符串,而是一個字節字符串,它仍然是可迭代的?

閱讀文檔;-) x不是「字符串」;這樣做是爲了看它的類型:

print(type(x)) 

,將顯示:

<class 'bytes'> 

這是一個bytes對象,簡單地已經解釋。這是一個序列,所以是的,它是可迭代的,就像所有的序列一樣。您也可以索引它,切片等。

您的y是一個列表。唉,我無法弄清楚你想用它來完成什麼。

我需要的是Y中同一類型爲x,使得outfile.write(X)= outfile.write(Y)

不,你不需要xy是相同的類型。你希望能夠寫作y作爲二進制數據。爲此,您需要創建一個bytesbytearray對象。這很容易;只是做其中的一個:

y = bytes(y) 

y = bytearray(y) 

然後

outfile.write(y) 

會做你想要什麼。

雖然,如上所述,我不知道爲什麼你在這裏創建一個列表開始。創建相同的列表更簡單的方法將是跳過所有的循環,只是寫:

y = list(x) 

如果我得到過,你應該開始懷疑你怎麼在這裏上的心智模式太複雜,不是太簡單。你正在想象那些並不存在的困難:-)從二進制文件中讀取給你一個bytes對象(或者如果你想讀取一個二進制文件來填充一個bytearray對象,請參閱文件.readinto()),同時寫入二進制文件需要給它一個bytesbytearray對象來寫。這裏的所有都是它的。

相關問題