2012-12-18 64 views
2

我有一个包含一系列比特的文本文件,在ASCII:蟒字面二进制进制转换

cat myFile.txt 
0101111011100011001... 

我想写这对以二进制模式的其它文件,这样我可以读取它一位君主。我怎么能达到?我试过已经用代码转换它:

f2=open(fileOut, 'wb') 
    with open(fileIn) as f: 
     while True: 
      c = f.read(1) 
      byte = byte+str(c) 
      if not c: 
       print "End of file" 
       break 
      if count % 8 is 0: 
       count = 0 
       print hex(int(byte,2)) 
       try: 
        f2.write('\\x'+hex(int(byte,2))[2:]).zfill(2) 
       except: 
        pass 
       byte = '' 
      count += 1 

但这并没有达到我计划要做的。你有什么提示吗?

回答

1

使用struct

import struct 
... 
f2.write(struct.pack('b', int(byte,2))) # signed 8 bit int 

​​
+0

谢谢你很多_ :-) – user1225343

2
  • 阅读并一次写一个字节是痛苦的缓慢。你可能会围绕〜45倍加速你的代码只需通过读取每次调用该文件的更多数据,以f.readf.write

    |------------------+--------------------| 
    | using_loop_20480 | 8.34 msec per loop | 
    | using_loop_8  | 354 msec per loop | 
    |------------------+--------------------| 
    

    using_loop在这个岗位的底部显示的代码。 using_loop_20480是chunksize = 1024 * 20的代码。这意味着每次从该文件读取20480个字节。 using_loop_1与chunksize = 1的代码相同。

  • 关于count % 8 is 0:请勿使用is来比较数值;改为使用==。下面是一些例子,为什么is可能会给你错误的结果(也许不是在您发布的代码,但在一般情况下,is是不恰当的位置):

    In [5]: 1L is 1 
    Out[5]: False 
    
    In [6]: 1L == 1 
    Out[6]: True 
    
    In [7]: 0.0 is 0 
    Out[7]: False 
    
    In [8]: 0.0 == 0 
    Out[8]: True 
    
  • 而不是

    struct.pack('{n}B'.format(n = len(bytes)), *bytes) 
    

    你可以使用

    bytearray(bytes) 
    

    不仅打字少,而且速度也稍微快一点。

    |------------------------------+--------------------| 
    |    using_loop_20480 | 8.34 msec per loop | 
    | using_loop_with_struct_20480 | 8.59 msec per loop | 
    |------------------------------+--------------------| 
    

    bytearrays是这项工作的良好匹配,因为它填补了关于数据作为字符串和 数字的序列之间的 差距。

    In [16]: bytearray([97,98,99]) 
    Out[16]: bytearray(b'abc') 
    
    In [17]: print(bytearray([97,98,99])) 
    abc 
    

    正如你可以看到上面,bytearray(bytes)允许你 通过使其整数的一个序列(在 range(256))定义字节组,并允许其写出,就好像是一个 字符串:g.write(bytearray(bytes))


def using_loop(output, chunksize): 
    with open(filename, 'r') as f, open(output, 'wb') as g: 
     while True: 
      chunk = f.read(chunksize) 
      if chunk == '': 
       break 
      bytes = [int(chunk[i:i+8], 2) 
        for i in range(0, len(chunk), 8)] 
      g.write(bytearray(bytes)) 

确保CHUNKSIZE是8的倍数。


这是我用来创建表的代码。需要注意的是prettytable也做类似这样的东西,它可能是最好使用自己的代码,而不是我砍:table.py

这是我来时使用的代码模块:utils_timeit.py。 (它使用table.py)。

这里是我用的时间using_loop(和其他变种)的代码:timeit_bytearray_vs_struct.py

+0

我喜欢你的表,什么是你的时间设置? – Kos

+1

@Kos:我编辑了我的帖子,并使用了我使用的代码的主要链接。我很抱歉,这是很多代码,并没有真正准备好发布。 – unutbu

+0

谢谢! ([2]和[3]指的是相同的链接,可能是一个错字)。我有点希望'timeit'有这个内置的地方;-)你的黑客似乎自动检测列的宽度,我不是当然,如果'prettytable'也能做到这一点。我有点记得寻找它,并最终自己写,但我不记得是否是关于'texttable'或'prettytable'包。 – Kos