2013-12-18 81 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对象来写。这里的所有都是它的。

相关问题