python中文本文件和二进制文件的区别_文本文件和二进制文件的区别

定义

广义的二进制文件即指文件,由文件在外部设备的存放形式为二进制而得名。狭义的二进制文件即除文本文件以外的文件。文本文件是一种由很多行字符构成的计算机文件。文本文件存在于计算机系统中,通常在文本文件最后一行放置文件结束标志。文本文件的编码基于字符定长,译码相对要容易一些;二进制文件编码是变长的,灵活利用率要高,而译码要难一些,不同的二进制文件译码方式是不同的。

从本质上来说他们之间没有什么区别,因为他们在硬盘上都有一种的存放方式--二进制,但是如果要对他们有些区分的话,那可以这样理解。每个字符由一个或多个字节组成,每个字节都是用的-128—127之间的部分数值来表示的,也就是说,-128——127之间还有一些数据没有对应任何字符的任何字节。如果一个文件中的每个字节的内容都是可以表示成字符的数据,我们就可以称这个文件为文本文件,可见,文本文件只是二进制文件中的一种特例,为了与文本文件相区别,人们又把除了文本文件以外的文件称为二进制文件,由于很难严格区分文本文件和二进制文件的概念,所以我们可以简单地认为,如果一个文件专门用于存储文本字符的数据,没有包含字符以外的其他数据,我们就称之为文本文件,除此之外的文件就是二进制文件。

使用二进制文件的好处

为什么要使用二进制文件。原因大概有三个:

第一是二进制文件比较节约空间,这两者储存字符型数据时并没有差别。但是在储存数字,特别是实型数字时,二进制更节省空间,比如储存 Real*4 的数据:3.1415927,文本文件需要 9 个字节,分别储存:3 . 1 4 1 5 9 2 7 这 9 个 ASCII 值,而二进制文件只需要 4 个字节(DB 0F 49 40)

第二个原因是,内存中参加计算的数据都是用二进制无格式储存起来的,因此,使用二进制储存到文件就更快捷。如果储存为文本文件,则需要一个转换的过程。在数据量很大的时候,两者就会有明显的速度差别了。

第三,就是一些比较精确的数据,使用二进制储存不会造成有效位的丢失。[1]

二进制文件的储存方式

列举一个二进制文件如下:

00000000h:0F 01 00 00 0F 03 00 00 12 53 21 45 58 62 35 34; .........S!EXb54

00000010h:41 42 43 44 45 46 47 48 49 47 4B 4C 4D 4E 4F 50; ABCDEFGHIGKLMNOP

这里列出的是在 UltraEdit(UE) 里看到的东西。其实只有红色部分是文件内容。前面的是 UE 加入的行号。后面的是 UE 尝试解释为字符型的参考。

这个文件一共有 32 字节长。显示为两列,每列 16 个字节。实际上,这仅仅是 UE 的显示而已。真实的文件并不分行。仅仅知道这个文件的内容,如果我们没有任何说明的话,是不能看出任何有用信息的。

下面我规定一下说明:我们认为,前 4 个字节是一个 4 字节的整型数据(0F 01 00 00 十六进制:10Fh 十进制:271)。这 4 个字节之后的 4 个字节是另一个 4 字节的整型数据(0F 03 00 00 十六进制:30Fh 十进制:783)。其后的 4 个字节(12 53 21 45 )表示一个 4 字节的实型数据:2.5811919E+3。再其后的 4 个字节(58 62 35 34)表示另一个 4 字节的实行数据:1.6892716E-7。而只后的 16 个字节(41 42 43 44 45 46 47 48 49 47 4B 4C 4D 4E 4F 50)我们认为是 16 个字节的字符串(ABCDEFGHIGKLMNOP)

实际上,二进制文件只是储存数据,并不写明数据类型,比如上面的第 9 字节到第 16 字节(12 53 21 45 58 62 35 34),我们刚才认为是 2 个 4 字节的实型,其实也可以认为是 8 个字节的字符型( S!EXb54)。而后面的 16 个字节的字符串(ABCDEFGHIGKLMNOP),我们也可以认为是 2 个 8 字节的整型,或者 4 个 4 字节的整型,甚至 2 个 8 字节的实型,4 个 4 字节的实型,等等等等。

因此,面对一个二进制文件,我们不能准确地知道它的含义,我们需要他的数据储存方式的说明。这个说明告诉我们第几个字节到第几个字节是什么类型的数据,储存的数据是什么含义。否则的话,我们只能猜测,或者无能为力。[1]

如何使用语句操作二进制文件

我们将上面的那个二进制文件保存为:TestBin.Bin 来举例。

读取和写入二进制其实是两个很类似的操作,了解了其中之一,另一个也就不难了。

二进制文件我们通常使用直接读取方式,Open 语句可以写为:

引用:

Open( 12 , File = 'TestBin.Bin' , Access = 'Direct' , Form = 'Unformatted' , RecL = 4 )

上面的 Access 表示直接读取方式,Form 表示无格式储存。比较重要的是 RecL 。我们读取数据时,是用记录来描述单位的,每一次读入或写入是一个记录。记录的长度在 Open 时就确定下来,以后不能改变。如果需要改变,只能 Close 以后再此 Open。

记录长度在某些编译器下表示读取的 4 字节长度的倍数,规定为 4 表示记录长度为 16 字节。有些编译器下就直接表示记录的字节数,规定为 4 则表示记录长度为 4 字节。这个问题需要参考编译器手册。在 VF 系列里,这个值是前面一个含义。可以通过设置工程属性的 Fortran,Data,Use Bytes as RECL= Unit for Unformatted Files 来改变,使之成为后一个含义。在命令行模式下,则使用 /assume:byterecl 这个编译选项。

确定 RecL 大小是我们需要做的事情,一般来说,不适合太大,也不适合太小。还需要结合数据储存方式来考虑。太小的话,我们需要执行读写的次数就多,太大的话,我们就不方便操作小范围的数据。

有时候我们甚至会分多次来读取数据,每一次的 RecL 都不同。对于上面的 TestBin.Bin 文件来说,它比较简单,我以 16 字节长度和 8 字节长度两种读取方式来演示,你甚至可以一次 32 个字节长度全部读完。[1]

用例

C++程序语言学习过程中常见名词,相对于Binary file的是Text file(纯文本文件)。

C++中二进制文件读写函数:

fread

fwrite

ifstream.read()

ofstream.write()

文件读

文件写

等等……

Java中二进制文件读写函数:

FileInputStream()

FileOutputStream()

文件输入流()

文件输出流()

等等……

那么,这个时候我们肯定会问:

汉字怎样转化为二进制代码?

各数制之间的转换

我们用R表示任何数制的基数,讨论各数制之间的转换。

1.R进制数转换为十进制数

二进制、八进制和十六进制数转换为等值的十进制数,只要把它们用多项式表示并在十进制下进行计算,所得的结果就是十进制数。

2.十进制数转换为R进制数

十进制数转换为等值的二进制、八进制和十六进制数,需要对整数部分和小数部分分别进行转换。其整数部分用连续除以基数R取余数的方法来完成,小数部分用连续乘以基数R取整数的方法来实现。

基数   基数   基数   基数   基数

十进制  10000  1000   100   10    1

二进制   16    8    4    2    1

八进制  4096   512    64   8    1

十六进制 65536  4096   256   16    1

3.二进制数与八进制数、十六进制数的转换

二进制数与八进制数的转换应以"3位二进制数对应1位八进制数"%的原则进行。同理,因为24=16,则二进制数与十六进制数的转换应以"4位二进制数对应1位十六进制数"的原则进行。

四、二进制数的运算

在计算机中,二进制数的运算包括算术运算和逻辑运算。

1.二进制数的算术运算

(1)二进制数加法

加法原则:逢二进一

(2)二进制数减法

减法原则:借一当二

(3)二进制数乘法

乘法原则:与算术乘法形式相同

(4)二进制数除法

除法原则:与算术除法形式相同

2.二进制数的逻辑运算

逻辑运算是以二进制数为基础的,逻辑变量只有两个,用来表示逻辑"真"和"假"。

(1)逻辑加法("或"运算)

运算符号:"+"或"∨"

运算规则:0+0=0;0+1=1;1+0=1;1+1=1;

(2)逻辑乘法("与"运算)

运算符号:"×"或"∧"

运算规则:0×0=0;0×1=0;1×0=0;1×1=1;

(3)逻辑"非"运算

运算符号:"-"%运算规则:A&-*=0时,A=1

五、数据类型及数据单位

1.数据的两种类型

计算机中的数据可概括分为两大类:数值型数据和字符型数据。所有的非数值型数据都要经过数字化后才能在计算机中存储和处理。

2.数据单位

在计算机中通常使用三个数据单位:位、字节和字。位的概念是:最小的存储单位,英文名称是bit,常用小写b或bit表示。用8位二进制数作为表示字符和数字的基本单元,

英文名称是byte,称为一字节。通常用大"B"表示。

1B(字节)=8b(位)

1KB(千字节)=1024B(字节)

1MB(兆字节)=1024KB(千字节)

字长:字长也称为字或计算机字,它是计算机能并行处理的二进制数的位数。

六、字符编码与汉字编码

1.字符编码

目前微型机中普遍采用的字符编码是ASCII码。它是用七位二进制数对127个字符进行编码,其中前32个是一些不可打印的控制符号。

2.汉字编码及字模信息

汉字有两种编码:国标码与机内码。

国标码是"中华人民共和国国家标准信息交换汉字编码",代号为"GB2312-80"。在国标码的字符集中,收集了一级汉字3755个,二级汉字3008个,图形符号682个,共7445个。一个汉字对应一个区位码,由四位数字组成,前两位数字为区码(0~94),后两位数字为位码(0~94)。机内码是指汉字在计算机中的编码

汉字的机内码占两个字节,分别称为机内码的高位与低位。它们与区位码的关系如下:

机内码高位=区码+A0H

机内码低位=位码+A0H

汉字字库是由所有汉字的字模信息构成的。一个汉字字模信息占若干字节,究竟占多少个字节由汉字的字形决定。

例如,如果用16×16点阵表示一个汉字,则一个汉字占16行,每行有16个点,在存储时用两个字节存放一行上16个点的信息,对应位为"0"表示该点为"白","1"表示该点为"黑"。因此,一个16×16点阵的汉字占32个字节。

---------------------------------------------------------------

描述2进制的数据结构,用字符串直观,但是效率低,用数组效率高,但是不直观。

但是道理相同。

性字转换后的结果:

010000010000 010010010000 010010010100 111011111110 110010010000 010100010000 010011111110 010000010000 010000010000 010000010000 010111111110 000000000000

144位编码,这也不可能的,

性字编码alert asc("性")得到-12076,转化为2进制为-10111100101100 不算正负有14位就够了。

如果非要补到144位也因该是高位补0。

function c10to2(x)

'10进制到2进制的转换

dim sign, result

result = ""

'符号

sign = sgn(x)

x = abs(x)

if x = 0 then

c10to2 = 0

exit function

end if

do until x = "0"

result = result & (x mod 2)

x = x \ 2

loop

result = strReverse(result)

if sign = -1 then

c10to2 = "-" & result

else

c10to2 = result

end if

end function

---------------------------------------------------------------

另外一个人的写法:

function c10to2(x)

mysign=sgn(x)

x=abs(x)

DigS=1

do

if x<2^DigS

二进制编码转汉字:

1. 汉字信息交换码(国标码)

《信息交换用汉字 编码字符集·基本集》是我国于1980年制定的国家标准 GB2312-80,代号为国标码,是国家规定的用于汉字信息处理使用的代码依据。

GB2312-80中规定了信息交换用的6763个汉字和682个非汉字图形符号(包括几种外文字母、数字和符号)的代码。

6763个汉字又按其 使用频度、组词能力以及用途大小分成一级常用汉字3755个和二级常用汉字3008个。

一级汉字按拼音字母顺序排列;若遇同音字,则 按起笔的笔形顺序排列;若起笔相同,则按第二笔的笔形顺序排列,依次类推。所谓笔形顺序,就是横、竖、撇、点和折的顺序。二级汉字按 部首顺序排列。

在此标准中,每个汉字(图形符号)采用双字节表示。每个字节只用低7位,最高位恒为1。由于低7位中有34种状态是用 于控制字符,因此,只有94(128-34=94)种状态可用于汉字编码。这样,双字节的低7位只能表示94×94=8836种状态。

编码范围

十进制数码

基本 ASCII 码

00000000~01111111

0~127

控制字符

00000000~00100000、01111111

0~32、127

可用汉字段

00100001~01111110

33~126 (1~94)

扩充 ASCII 码

10000000~11111111

128~255

控制字符

10000000~10100000、11111111

128~160、255

GB2312-80

10100001~11111110

161~254 (1~94)

此标准的汉字编码表有94行、94列,其行号称为区号,列号称为位号。双字节中,用 高字节表示区号,低字节表示位号。非汉字图形符号置于第1~11区,一级汉字3755个且于第16~55区,二级汉字3008个置于第56~87区。

每个图形字符的汉字交换码,均用两个字节的低7位二进制码表示。汉字国标码通常用十六进制数表示。

例如:“中”字的区号为 54,位号为48,计算它的二进制数和十六进制数国标码。

解:先将区、位号分别加上 32 :

54+32=86

48+32=80

分别转换为二进制数:

(86)10=01010110

(80)10=0 1010000

得到二进制数国标码为:

01010110 01010000。

最后通过 8 4 2 1 ── 二进制取位法转换成十六 进制汉字国标码为:5650。

又如“国”字的区号为25,位号为90,用以上相同的方法得到它的国标码为:

二进制:00111001 01111010

十六进制:397A

----------------------------------------------------------------

基于以上原则,则

11000100,11100011,10111010,11000011

>(1100 0100 1110 0011)2,(1011 1010 1100 0011)2

>(C4E3)16,(BAC3)16

>查表可知:C4E3>>‘你’,BAC3>>‘好’

你可能感兴趣的:(python中文本文件和二进制文件的区别_文本文件和二进制文件的区别)