python⼆进制⽂件对⽐_⼆进制⽂件.VS.⽂本⽂件>python 【前⾔】
最近⽤python读⼆进制⽂件,遇到⼀个问题:我的⼆进制⽂件⾥⾯掺杂着正常的⽂本,我想将⾥⾯的⽂本给剔除掉。解决这个问题就是写这篇⽂章的初衷。
⼀、预备知识
⼆进制⽂件和⽂本⽂件有啥区别呢?百度知道 ⾥⾯有位⼤佬说:在定义和存取⽅式上⼆进制⽂件与⽂本⽂件存在区别。
1、定义上的区别
⽂本⽂件:⽂本⽂件是⼀种计算机⽂件,它是⼀种典型的顺序⽂件,其⽂件的逻辑结构⼜属于流式⽂件。简单的说,⽂本⽂件是基于字符编码的⽂件,常见的编码有ASCII编码,UNICODE编码等等。
⼆进制⽂件:是基于值编码的⽂件,你可以根据具体应⽤,指定某个值是什么意思(这样⼀个过程,可以看作是⾃定义编码)。⽤户⼀般不能直接读懂它们,只有通过相应的软件才能将其显⽰出来。⼆进制⽂件⼀般是可执⾏程序、图形、图像、声⾳等等。
从上⾯可以看出⽂本⽂件与⼆进制⽂件的区别并不是物理上的,⽽是逻辑上的。这两者只是在编码层次
上有差异,⽂本⽂件基本上是定长编码的(也有⾮定长的编码如UTF-8)。⽽⼆进制⽂件则可看成是变长编码,因为是值编码,多少个⽐特代表⼀个值,完全由你决定。
2、存储⽅式上的区别
⽂本⼯具打开⼀个⽂件,⾸先读取⽂件物理上所对应的⼆进制⽐特流,然后按照所选择的解码⽅式来解释这个流,然后将解释结果显⽰出来。
⼀般来说,你选取的解码⽅式会是ASCII码形式(ASCII码的⼀个字符是8个⽐特),接下来,它8个⽐特8个⽐特地来解释这个⽂件流。
记事本⽆论打开什么⽂件都按既定的字符编码⼯作(如ASCII码),所以当他打开⼆进制⽂件时,出现乱码也是很必然的⼀件事情了,解码和译码不对应。
⽂本⽂件的存储与其读取基本上是个逆过程。⽽⼆进制⽂件的存取与⽂本⽂件的存取差不多,只是编/解码⽅式不同⽽已。
⼆进制⽂件就是把内存中的数据按其在内存中存储的形式原样输出到磁盘中存放,即存放的是数据的原形式。⽂本⽂件是把数据的终端形式的⼆进制数据输出到磁盘上存放,即存放的是数据的终端形式
3、⽂本⽂件和⼆进制⽂件的优缺点:
⼀般认为,⽂本⽂件编码基于字符定长,译码容易些;⼆进制⽂件编码是变长的,所以它灵活,存储利⽤率要⾼些,译码难⼀些(不同的⼆进制⽂件格式,有不同的译码⽅式)。
关于空间利⽤率,想想看,⼆进制⽂件甚⾄可以⽤⼀个⽐特来代表⼀个意思(位操作),⽽⽂本⽂件任何⼀个意思⾄少是⼀个字符。
在windows下,⽂本⽂件不⼀定是以ASCII来存贮的,因为ASCII码只能表⽰128的标识,你打开⼀个txt⽂档,然后另存为,有个选项是编码,可以选择存贮格式,⼀般来说UTF-8编码格式兼容性要好⼀些。⽽⼆进制⽤的计算机原始语⾔,不存在兼容性。
如果存储的是字符数据,⽆论采⽤⽂本⽂件还是⼆进制⽂件都是没有任何区别的。如果存储的是⾮字符数据,⼜要看我们使⽤的情况来决定:
1、如果是需要频繁的保存和访问数据,那么应该采取⼆进制⽂件进⾏存放,这样可以节省存储空间和转换时间。
2、如果需要频繁的向终端显⽰数据或从终端读⼊数据,那么应该采⽤⽂本⽂件进⾏存放,这样可以节省转换时间。
⼆、Python 读取
好像对于⽂本⽂件,不论是⼆进制⽅式读取还是⽂本⽅式读取,都可以;但是对于⼆进制⽂件,只可以⼆进制⽅式读取,⽤⽂本⽅式读取的话会报错的。
Python 读取⽂本⽂件不⽤多说,关键是⼆进制⽂件。
#读取⽂本⽂件
f=open('','r');
adlines()
f.close()
读⼆进制⽂件,就来个压缩包吧,最近就是搞压缩包遇到问题,才想写这篇⽂章的。
filename=r'C:\Users\OHanlon\Documents\python\temp\ABPO00MDG_R_20191010000_01D_'
adlines()
l1=fblist[0] #b'HTTP/1.1 200 OK\r\n'
l15=fblist[14] #b"\xe3\xe0\x87\x91\xc..
#上⾯只是⼀部分
type(l1) #
type(l15) #
上⾯这个⽂件情况是这样的:⽤npp打开的时候,可以看到它前⾯有⼏⾏是⽂本,然后后⾯是乱码。通过上⾯python以⼆进制⽅式读取的话,直观上看,可以很明显地区分出来⽂本和⼆进制语句。
Python2 和Python3 读取⼆进制⽂件的区别
python3:
python2:
从上⾯可以看出来:python2 以⼆进制⽅式读⽂件读出来的是字符串,python3读⼆进制⽂件,读出来的是bytes。
我上⾯是⽤python3读取的,下⾯先考虑python3的情况。
sl1=str(l1) # "b'HTTP/1.1 200 OK\\r\\n'"
sl15=str(l15) # 'b"\\xe3\\xe0\\x87\\x91\\xc..
将bytes 转化成 str ;这样就很容易看出来区别了:
好,上⾯已经解决了python3 的问题:r'\x' in str(xx) 返回 true 就是⼆进制语句,返回false就是正常的⽂本语句。那么对于python2 怎么解决呢?(实际上我的问题已经得以解决,但是处于好奇,多尝试⼀下嘛)
先切换到 16 进制视图看下⽂件:
注:这个⽂件,前13⾏是⽂本。
python怎么读文件夹下的文件夹
发现并没有好的标志,做了初步尝试:
然后在⽹上搜了搜,发现有篇⽂章:
⽂章中的⼩函数如下(注意,是Python2):
#Check if a string is text or binary
'''If the string contains control or more than 30% of the characters in the string are 1, then it is binary
data'''
import string
text = ''.join(map(chr,range(32,127))) + '\r\n\t\b'
_null_trans = string.maketrans('','')
def istext(s,text = text,threshold = 0.30):
if '\0' in s:
return False
if not s:
return True
t = s.translate(_null_trans,text) #delete char in text for s
return len(t)/(len(s) * 1.0) <= threshold
进⾏测试:
file='ABPO00MDG_R_20191010000_01D_'
fb=open(file,'rb')
adlines()
l1=flist[0]
l15=flist[14]
fb.close()
import test; print test.istext(l1); print test.istext(l15)
perfect!
⾄此,在python2 和python3 中都已完美解决我遇到的问题!
三、Python 中 str 和 bytes 的相互转换
>>> str='ohanlon'
>>> de('utf-8')
>>> bstr
b'ohanlon'
>>> str1=bstr.decode('utf-8')
>>> str1
'ohanlon'
>>> del str #得把str删了,不然下⾯那⾏会将str认为是变量str,这样就执⾏不了。
>>> str(bstr)
"b'ohanlon'"
>>> repr(bstr)
"b'ohanlon'"
【⽂章总结】
de('utf-8') str转bytes
str1=bstr.decode('utf-8') bytes转str
python3与python2的区别:python2⽀持print xx 和print(xx),⽽python3 只⽀持后者。python3 以⼆进制形式读⽂件出来的是bytes,⽽python2以⼆进制形式读⽂件读出来的是str。
为解决消除⼆进制⽂件中的⽂本信息,在python3中的解决⽅案是r'\x' in str(xx) 返回 true 就是⼆进制语句,返回false就是正常的⽂本语句;在python2 中的解决⽅案是加个⼩函数,istext(xx) 返回 false 就是⼆进制语句,返回true就是正常的⽂本语句。
python2中的⼩函数如下:
#Check if a string is text or binary
'''If the string contains control or more than 30% of the characters in the string are 1, then it is binary data'''
import string
text = ''.join(map(chr,range(32,127))) + '\r\n\t\b'
_null_trans = string.maketrans('','')
def istext(s,text = text,threshold = 0.30):
if '\0' in s:
return False
if not s:
return True
t = s.translate(_null_trans,text) #delete char in text for s
return len(t)/(len(s) * 1.0) <= threshold

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。