精华内容
下载资源
问答
  • 文本文件和二进制文件的差异区别

    万次阅读 多人点赞 2018-05-16 11:11:20
    广义上的二进制文件包括文本文件,这里讨论的是狭义上的二进制文件文本文件的比较: 能存储的数据类型不同 文本文件只能存储char型字符变量。二进制文件可以存储char/int/short/long/float/……各种变量值。 每...

    广义上的二进制文件包括文本文件,这里讨论的是狭义上的二进制文件与文本文件的比较:

    1. 能存储的数据类型不同
      文本文件只能存储char型字符变量。二进制文件可以存储char/int/short/long/float/……各种变量值。
    2. 每条数据的长度
      文本文件每条数据通常是固定长度的。以ASCII为例,每条数据(每个字符)都是1个字节。进制文件每条数据不固定。如short占两个字节,int占四个字节,float占8个字节……
    3. 读取的软件不同
      文本文件编辑器就可以读写。比如记事本、NotePad++、Vim等。二进制文件需要特别的解码器。比如bmp文件需要图像查看器,rmvb需要播放器……
    4. 操作系统对换行符(‘\n’)的处理不同(不重要)
      文本文件,操作系统会对’\n’进行一些隐式变换,因此文本文件直接跨平台使用会出问题。
      在Windows下,写入’\n’时,操作系统会隐式的将’\n’转换为”\r\n”,再写入到文件中;读的时候,会把“\r\n”隐式转化为’\n’,再读到变量中。
      在Linux下,写入’\n’时,操作系统不做隐式变换。
      二进制文件,操作系统不会对’\n’进行隐式变换,很多二进制文件(如电影、图片等)可以跨平台使用。

    从存储方式来说,文件在磁盘上的存储方式都是二进制形式,所以,文本文件其实也应该算二进制文件。先从他们的区别来说,虽然都是二进制文件,但是二进制代表的意思不一样。打个比方,一个人,我们可以叫他的大名,可以叫他的小名,但其实都是代表这个人。二进制读写是将内存里面的数据直接读写入文本中,而文本呢,则是将数据先转换成了字符串,再写入到文本中。

    要弄明白二者的区别,需要知道文件的读写过程。以读文件为例,

    实际上是磁盘 》》 文件缓冲区》》应用程序内存空间这两个转化过程。我们说“文本文件和二进制文件没有区别”,实际上针对的是第一个过程;既然没有区别,那么打开方式不同,为何显示内容就不同呢?这个区别实际上是第二个过程造成的。

    文件实际上包括两部分,控制信息和内容信息。纯文本文件仅仅是没有控制格式信息罢了;

    实际上也是一种特殊的二进制文件。所以,我们很难区分二者的不同,因为他们的概念上不是完全互斥的。我们说文本文件是特殊的二进制文件,是因为文本文件实际上的解释格式已经确定了:ASCII或者unicode编码。文本文件的一个缺点是,它的熵往往较低,也就是说,其实本可以用更小的存储空间记录这些信息。比如,文本文件中的一个数字65536,需要用5个字节来存储;但是用二进制格式,采用int存储,仅仅需要2个字节。而二进制文件elf和bmp等,都往往有一个head,告诉你文件信息和解释方式。

    记事本支持文本文件而不支持二进制文件,所以如果你用记事本打开文本文件那么一切正常,如果打开的是二进制文件就会出现乱码。但也有不乱码的地方,你会注意到那些地方都是字符编码的,而对于int、double等类型所对应的值都是乱码的,这是由于记事本只能够识别字符类型,而无法识别其他类型。

    1、二进制文件是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放,也就是说存放的是数据的原形式。

    2、文本文件是把数据的终端形式的二进制数据输出到磁盘上存放,也就是说存放的是数据的终端形式。

    字符数据本身在内存中就经过了编码,所以无论是二进制还是文本形式都是一样的,而对于非字符数据来说,例如inti=10;如果用二进制来进行存储的话为1010,但是如果需要用文本形式来进行存储的话就必须进行格式化编码(对1和0分别编码,即形式为‘1’和‘0’分别对应的码值)。



    一、文本文件与二进制文件的定义

    大家都知道计算机的存储在物理上是二进制的,所以文本文件与二进制文件的区别并不是物理上的,而是逻辑上的。这两者只是在编码层次上有差异。简单来说,文本文件是基于字符编码的文件,常见的编码有ASCII编码,UNICODE编码等等。二进制文件是基于值编码的文件,你可以根据具体应用,指定某个值是什么意思(这样一个过程,可以看作是自定义编码。

    从上面可以看出文本文件基本上是定长编码的(也有非定长的编码如UTF-8)。而二进制文件可看成是变长编码的,因为是值编码嘛,多少个比特代表一个值,完全由你决定。大家可能对BMP文件比较熟悉,就拿它举例子吧,其头部是较为固定长度的文件头信息,前2字节用来记录文件为BMP格式,接下来的8个字节用来记录文件长度,再接下来的4字节用来记录bmp文件头的长度。

    二、文本文件与二进制文件的存取

    文本工具打开一个文件的过程是怎样的呢?拿记事本来说,它首先读取文件物理上所对应的二进制比特流,然后按照你所选择的解码方式来解释这个流,然后将解释结果显示出来。一般来说,你选取的解码方式会是ASCII码形式(ASCII码的一个字符是8个比特),接下来,它8个比特8个比特地来解释这个文件流。例如对于这么一个文件流”01000000_01000001_01000010_01000011”(下划线”_”,为了增强可读性手动添加的),第一个8比特”01000000”按ASCII码来解码的话,所对应的字符是字符”A”,同理其它3个8比特可分别解码为”BCD”,即这个文件流可解释成“ABCD”,然后记事本就将这个“ABCD”显示在屏幕上。

    事实上,世界上任何东西要与其他东西通信会话,都存在一个既定的协议,既定的编码。人与人之间通过文字联络,汉字“妈”代表生你的那个人,这就是一种既定的编码。但注意到这样一种情况,汉字“妈”在日本文字里有可能是你生下的那个人,所以当一个中国人A与日本B之间用“妈”这个字进行交流,出现误解就很正常的。用记事本打开二进制文件与上面的情况类似。记事本无论打开什么文件都按既定的字符编码工作(如ASCII码),所以当他打开二进制文件时,出现乱码也是很必然的一件事情了,解码和译码不对应嘛。例如文件流”00000000_00000000_00000000_00000001”可能在二进制文件中对应的是一个四字节的整数int 1,在记事本里解释就变成了”NULL_NULL_NULL_SOH”这四个控制符。

    文本文件的存储与其读取基本上是个逆过程。而二进制文件的存取显然与文本文件的存取差不多,只是编/解码方式不同而已。

    三、文本文件与二进制文件的优缺点

    因为文本文件与二进制文件的区别仅仅是编码上不同,所以他们的优缺点就是编码的优缺点,这个找本编码的书来看看就比较清楚了。一般认为,文本文件编码基于字符定长,译码容易些;二进制文件编码是变长的,所以它灵活,存储利用率要高些,译码难一些(不同的二进制文件格式,有不同的译码方式)。关于空间利用率,想想看,二进制文件甚至可以用一个比特来代表一个意思(位操作),而文本文件任何一个意思至少是一个字符。

    在windows下,文本文件不一定是一ASCII来存贮的,因为ASCII码只能表示128的标识,你打开一个txt文档,然后另存为,有个选项是编码,可以选择存贮格式,一般来说UTF-8编码格式兼容性要好一些.而二进制用的计算机原始语言,不存贮兼容性. 很多书上还认为,文本文件的可读性要好些,存储要花费转换时间(读写要编译码),而二进制文件可读性差,存储不存在转换时间(读写不要编解码,直接写值).这里的可读性是从软件使用者角度来说的,因为我们用通用的记事本工具就几乎可以浏览所有文本文件,所以说文本文件可读性好;而读写一个具体的二进制文件需要一个具体的文件解码器,所以说二进制文件可读性差,比如读BMP文件,必须用读图软件。

    而这里的存储转换时间应该是从编程的角度来说的,因为有些操作系统如windows需要对回车换行符进行转换(将”\n”,换成”\r\n”,所以文件读写时,操作系统需要一个一个字符的检查当前字符是不是”\n”或”\r\n”).这个在存储转换在Linux操作系统中并不需要,当然,当在两个不同的操作系统上共享文件时,这种存储转换又可能出来。



    文本文件是一种计算机文件,它是一种典型的顺序文件,其文件的逻辑结构又属于流式文件。

    特别的是,文本文件是指以ASCII码方式(也称文本方式)存储的文件,更确切地说,英文、数字等字符存储的是ASCII码,而汉字存储的是机内码。文本文件中除了存储文件有效字符信息(包括能用ASCII码字符表示的回车、换行等信息)外,不能存储其他任何信息。

    文本文件是一种由若干行字符构成的计算机文件。文本文件存在于计算机文件系统中。通常,通过在文本文件最后一行后放置文件结束标志来指明文件的结束。文本文件是指一种容器,而纯文本是指一种内容。文本文件可以包含纯文本。一般来说,计算机文件可以分为两类:文本文件和二进制文件。

    只含有ASCII字符的文本文件可以在Unix、Macintosh、Microsoft Windows、DOS和其它操作系统之间自由交互,而其它格式的文件是很难做到这一点的。但是,在这些操作系统中,换行符并不相同,处理非ASCII字符的方式也不一致。

    .txt是包含极少格式信息的文字文件的扩展名。.txt格式并没有明确的定义,它通常是指那些能够被系统终端或者简单的文本编辑器接受的格式。任何能读取文字的程序都能读取带有.txt扩展名的文件,因此,通常认为这种文件是通用的、跨平台的。

    在英文文本文件中,ASCII字符集是最为常见的格式,而且在许多场合,它也是默认的格式。对于带重音符号的和其它的非ASCII字符,必须选择一种字符编码。在很多系统中,字符编码是由计算机的区域设置决定的。常见的字符编码包括支持许多欧洲语言的ISO 8859-1。

    由于许多编码只能表达有限的字符,通常它们只能用于表达几种语言。Unicode制定了一种试图能够表达所有已知语言的标准,Unicode字符集非常大,它囊括了大多数已知的字符集。Unicode有多种字符编码,其中最常见的是UTF-8,这种编码能够向后兼容ASCII,相同内容的的ASCII文本文件和UTF-8文本文件完全一致。

    微软的MS-DOS和Windows采用了相同的文本文件格式,它们都使用CR和LF两个字符作为换行符,这两个字符对应的ASCII码分别为13和10。通常,最后一行文本并不以换行符(CR-LF标志)结尾,包括记事本在内的很多文本编辑器也不在文件的最后添加换行符。

    大多数Windows文本文件使用ANSI、OEM或者Unicode编码。Windows所指的ANSI编码通常是1字节的ISO-8859编码,不过对于像中文、日文、朝鲜文这样的环境,需要使用2字节字符集。在过渡至Unicode前,Windows一直用ANSI作为系统默认的编码。而OEM编码,也是通常所说的MS-DOS代码页,是IBM为早期IBM个人电脑的文本模式显示系统定义的。在全屏的MS-DOS程序中同时使用了图形的和按行绘制的字符。新版本的Windows可以使用UTF-16LE和UTF-8之类的Unicode编码。

    由于结构简单,文本文件被广泛用于记录信息。它能够避免其它文件格式遇到的一些问题。此外,当文本文件中的部分信息出现错误时,往往能够比较容易的从错误中恢复出来,并继续处理其余的内容。文本文件的一个缺点是,它的熵往往较低,也就是说,可以用较小的存储空间记录这些信息。

    文本文件基本上是定长编码的(也有非定长的编码如UTF-8),基于字符,每个字符在具体编码中是固定的,ASCII码是8个比特的编码,UNICODE一般占16个比特。而二进制文件可看成是变长编码的,因为是值编码,多少个比特代表一个值,完全由自己决定。

    广义的二进制文件即指文件,由文件在外部设备的存放形式为二进制而得名。狭义的二进制文件即除文本文件以外的文件。

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

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

    第一是二进制文件比较节约空间,这两者储存字符型数据时并没有差别。但是在储存数字,特别是实型数字时,二进制更节省空间;第二个原因是,内存中参加计算的数据都是用二进制无格式储存起来的,因此,使用二进制储存到文件就更快捷。如果储存为文本文件,则需要一个转换的过程。在数据量很大的时候,两者就会有明显的速度差别了。第三,就是一些比较精确的数据,使用二进制储存不会造成有效位的丢失。



    转自:

    1. 文本文件和二进制文件的差异和区别
    2. 文本文件与二进制文件区别
    展开全文
  • 记事本无论打开什么文件都按既定的字符编码工作(如ASCII码),所以当他打开二进制文件时,出现乱码也是很必然的一件事情了,解码译码不对应嘛。例如文件流”00000000_00000000_00000000_0000000...

    二进制文件

    • 定义: 二进制文件就是把内存中的数据按其在内存中存储的形式原样输出到磁盘中存放,即存放的是数据的原形式。二进制文件是包含在 ASCII 及扩展 ASCII 字符中编写的数据或程序指令的文件。一般是可执行程序、图形、声音等文件,有自己特殊的编解码格式。不同的应用程序对二进制文件中的每个值会有不同的解读,要打开二进制文件需要对应的二进制文件解码器。

    • 读取流程: 用记事本打开二进制文件的流程是怎样的呢?记事本无论打开什么文件都按既定的字符编码工作(如ASCII码),用ASCII码的规则去解读二进制文件时,会出现乱码。所以当他打开二进制文件时,出现乱码也是很必然的一件事情,解码和译码不对应。例如文件流”00000000_00000000_00000000_00000001”可能在二进制文件中对应的是一个四字节的整数int 1,在记事本里解释就变成了”NULL_NULL_NULL_SOH”这四个控制符。文本文件将浮点数80.000000用了38(表示8) 30(表示0) 2E(表示.) 30(表示0) 30(表示0) 30(表示0) 30(表示0) 30(表示0) 30(表示0),二进制文件用了4个字节表示浮点数00 00 A0 42。字符型的内容都是ASCii码的形式,没有区别。

    • 例子: 在计算机中,所有的颜色都可以映射为一个二进制的值。图片存储时,图片上每个点都有自己的颜色值,将每个点的颜色值,以及图片本身的宽高信息储存起来,就是最基本的位图存储(bmp),位图存储是没有压缩的。将位图信息,经过二次编码,压缩就形成了压缩后的图片。算法不同产生的图片格式也有区别。常见的包括jpg,png,gif等。文本文件基本上是定长编码的(也有非定长的编码如UTF-8)。而二进制文件可看成是变长编码的,因为是值编码,多少个比特代表一个值,完全由自定义的编解码规则决定。像BMP文件,其头部是较为固定长度的文件头信息,前2字节用来记录文件为BMP格式,接下来的8个字节用来记录文件长度,再接下来的4字节用来记录bmp文件头的长度。

    • linux 二进制的兼容性: Linux上二进制有一个显著的特点就是可移植性不强。我们在不同的发行版之间,不同的内核版本之间,程序往往是不能通用的,比如把ubunbtu下面编译的二进制可执行文件拷贝到CentOS上,基本不可能运行。原因是程序总需要使用或多或少的系统调用,系统调用是核心代码实现的,核心不同自然也就不兼容了。另外不同系统的对执行文件加载方式也不同。
      如果应用对内核kernel版本有要求,则不建议使用docker,docker底层复用的host的kernel.,如果可以用docker,可以解决除kernel版本外的兼容性问题,build once run everywhere。

    文本文件

    • 定义: 文本文件是把数据的终端形式的二进制数据输出到磁盘上存放,即存放的是数据的终端形式. 文本文件(也称为ASCII文件):它的每一个字节存放的是可表示为一个字符的ASCII代码的文件。它是以 “行”为基本结构的一种信息组织和存储方式的文件,可用任何文字处理程序阅读的简单文本文件。

    • 读取流程: 文本工具打开一个文件的过程是怎样的呢?拿记事本来说,它首先读取文件物理上所对应的二进制比特流,然后按照你所选择的解码方式来解释这个流,然后将解释结果显示出来。一般来说,你选取的解码方式会是ASCII码形式(ASCII码的一个字符是8个比特),接下来,它8个比特8个比特地来解释这个文件流。例如对于这么一个文件流”01000000_01000001_01000010_01000011”, 第一个8比特”01000000”按ASCII码来解码的话,所对应的字符是字符”A”,同理其它3个8比特可分别解码为”BCD”,即这个文件流可解释成“ABCD”,然后记事本就将这个“ABCD”显示在屏幕上。

    • 选择: 如果是需要频繁的保存和访问数据,那么应该采取二进制文件进行存放,这样可以节省存储空间和转换时间。
      如果需要频繁的向终端显示数据或从终端读入数据,那么应该采用文本文件进行存放,这样可以节省转换时间。

    • 区别: window 文本模式中,在存储\n时要转化为\r\n,读取文件时进行逆转换。window二进制模式时,则不进行转换。

    • ^m原因: 回车和换行是不相同的,Windows中文字另起一行内存表示为<回车><换行>对应\r\n,而Linux、Unix中则是单单一个<换行>对应\n。Mac中则是一个<回车>对应\r。C语言起源于Unix的产生,对于文件中的另起一行,Unix采用单个\n表示,我们通常在输出换行时加一个\n就可以了,Windows也是如此。到了数据从内存到硬盘上进行存储时,对于unix来说,\n照样是\n,在Linux下,二进制文件和文本文件都是以’\n’作为行结束符,所以不需要转换,而Windows为了防止读取时混乱必须转换为\r\n。Windows 格式的文本文件,用\r\n 作为换行符,而Unix 的则是以\n作为换行符,所以dos 底下的文本文件到了unix的话,换行符就会多出来一个 0D(CR) 显示为 ^M。

    在这里插入图片描述

    结构体写入文件

    • 结构体写入文件:C语言把文件看作一个字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。根据数据的组织形式,可分为ASCII文件和二进制文件。ASCII文件又称为文本(text)文件,它的每个字节放一个ASCII代码,代表一个字符。二进制文件是把内存中的数据按其在内在中的存储形式原样输出到磁盘上存放。二进制将数据在内存中的样子原封不动的搬到文件中,文本格式则是将每一个数据转换成字符写入到文件中,他们在大小上,布局上都有着区别。由此可以看出,二进制文件可以读出来直接用,但是文本文件还多一个“翻译”的过程,因此二进制文件的可移植性好。
    • C语言把一个结构体数组写入文件分三步:
      1、以二进制写方式(wb)打开文件
      2、调用写入函数fwrite()将结构体数据写入文件
      3、关闭文件指针
      相应的,读文件也要与之匹配:
      1、以二进制读方式(rb)打开文件
      2、调用读文件函数fread()读取文件中的数据到结构体变量
      3、关闭文件指针
    • fwrite :函数按照指定的数据类型将矩阵中的元素写入到文件中。写二进制文件其调用格式为:COUNT=fwrite (fd, A, precision)其中COUNT返回所写的数据元素个数,fd为文件句柄,A用来存放写入文件的数据,precision用于控制所写数据的类型,其形式与fread函数相同。当我们按照二进制方式往文件中写入数据,则将数据在内存中的存储形式原样输出到文件中。用fwrite 写入文件的如果是字符,那么就会显示为字符,写入的是数字显示不出来,写的是二进制内容(所谓的乱码)
    • fprintf :写文本文件 函数的调用格式为:COUNT= fprintf(fd, format, A)其中A存放要写入文件的数据。先按format指定的格式将数据矩阵A格式化,然后写入到fid所指定的文件。format用以控制读取的数据格式,由%加上格式符组成,常见的格式符有d,f,c,s。fid为文件句柄。fprintf写的是数字转换成ASCII码之后的字符。
    • 当使用fwrite将一个int型数字65写入文本文件时,由于65对应的二进制数是1000001,十六进制数是0x41,存储的是以二进制的形式1000001.在notepad++中使用十六进制方式打开显示的是:0x0041,转换为十进制则为65。记事本打开可能存在乱码,因为fwrite在写入的时候是采用整字节的二进制写入,而文本编辑器采用的是ascll码显示,两者不兼容。
    • 当使用fpintf将一个int型数字65写入文本文件时,将65每一位转换为ASCII码存储,6、5分别对应ASCII码54、53,存储的是ASCII码54、53.在notepad++中使用十六进制方式打开显示的是:3635,转换为十进制则为54、53,这正是数字6、5的ASCII码。使用记事本打开这个文本文件时,记事本将存储在其中的54、53当做ASCII码翻译为字符6、5显示,我们看到的是便是字符65。
    • 二进制读写是将内存里面的数据直接读写入文本中,而文本呢,则是将数据先转换成了字符串,再写入到文本中。下面我用个例子来说明。
      我们定义了一个结构体,表示一个学生信息,我们打算把学生的信息分别用二进制和文本的方式写入到文件中。
    struct Student 
    {
        int num;
        char name[20];
        float score;
    };
    我们定义两个方法,分别表示内存写入和文本写入
    //使用二进制写入
    void write_to_binary_file()
    {
        struct Student stdu;
        stdu.num = 111;
        sprintf_s(stdu.name,20,"%s","shine");
        stdu.score = 80.0f;
        fstream binary_file("test1.dat",ios::out|ios::binary|ios::app); //此处省略文件是否打开失败的判断
        binary_file.write((char *)&stdu,sizeof(struct Student));//二进制写入的方式
        binary_file.close();
    } 
    //文本格式写入
    void write_to_text_file()
    {
        struct Student stdu;
        stdu.num = 111;
        sprintf_s(stdu.name,20,"%s","shine");
        stdu.score = 80.0f;
        FILE *fp = fopen("test2.dat","a+");   //此处省略文件是否打开失败的判断
        fprintf(fp,"%d%s%f",stdu.num,stdu.name,stdu.score); //将数据转换成字符串(字符串的格式可以自己定义)
        fclose(fp);
    } 
    //MAIN函数调用前面两个方法
    int _tmain(int argc, _TCHAR* argv[])
    {
        write_to_binary_file();
        write_to_text_file();
        
        return 0;
    }
    

    二进制 图
    二进制文件
    文本文件 图
    文本文件

    • stdu.num = 111: 二进制文件里面将111编码成6F,1个字节,这刚好是111的16进制表示,而文本文件中则写成31 31 31用了3个字节,表示111。
    • stdu.name = “shine”: 二进制和文本文件中73 68 69 6E 65都表示shine,这体现对字符数据处理的一致性。
    • stdu.score = 80.0f: 二进制文件里是几个连续的FE,而文本文件中是38 30…。文本文件将浮点数80.000000用了38(表示8) 30(表示0) 2E(表示.) 30(表示0) 30(表示0) 30(表示0) 30(表示0) 30(表示0) 30(表示0),二进制文件用了4个字节表示浮点数00 00 A0 42
    • 通过这里我们可以初见端倪了,二进制将数据在内存中的样子原封不动的搬到文件中,文本格式则是将每一个数据转换成字符写入到文件中,他们在大小上,布局上都有着区别。由此可以看出,二进制文件可以从读出来直接用,但是文本文件还多一个“翻译”的过程,因此二进制文件的可移植性好。
    展开全文
  • 对固件二进制文件的字符串进行分析的时候,常常用到字符串比较的情况。 那么比较两个文件的字符串相同的部分不需要写程序去实现,直接使用命令就可以了。 具体的步骤: 输出两个二进制文件的字符串信息,使用...

     对固件二进制文件的字符串进行分析的时候,常常用到字符串比较的情况。

    那么比较两个文件的字符串相同的部分不需要写程序去实现,直接使用命令就可以了。

    具体的步骤:

    输出两个二进制文件的字符串信息,使用Strings工具命令;

    将两个二进制文件的内容按照字母表等排序;cat file | sort > newfile

    比较两个文件的异、同comm file1 file2;

    比较两个文件的不同点 comm file1 file2 -1 -2 。

    具体详细的使用方法如下图所示:

    展开全文
  • ofstream/ifstream 文本/二进制 方式 读入/写出 数据方法 ... 在这篇文章里,我会详细解释ASCII和二进制文件的输入输出的每个细节,值得注意的是,所有这些都是用C++完成的。  一、ASCII 输出

     

    转自:http://www.cnblogs.com/cy163/archive/2007/05/26/760426.html

    ofstream/ifstream 文本/二进制 方式 读入/写出 数据方法
    文件 I/O 在C++中比烤蛋糕简单多了。 在这篇文章里,我会详细解释ASCII和二进制文件的输入输出的每个细节,值得注意的是,所有这些都是用C++完成的。

      一、ASCII 输出

      为了使用下面的方法, 你必须包含头文件<fstream.h>(译者注:在标准C++中,已经使用<fstream>取代< fstream.h>,所有的C++标准头文件都是无后缀的。)。这是 <iostream.h>的一个扩展集, 提供有缓冲的文件输入输出操作. 事实上, <iostream.h> 已经被<fstream.h>包含了, 所以你不必包含所有这两个文件, 如果你想显式包含他们,那随便你。我们从文件操作类的设计开始, 我会讲解如何进行ASCII I/O操作。如果你猜是"fstream," 恭喜你答对了! 但这篇文章介绍的方法,我们分别使用"ifstream"?和 "ofstream" 来作输入输出。

      如果你用过标准控制台流"cin"?和 "cout," 那现在的事情对你来说很简单。 我们现在开始讲输出部分,首先声明一个类对象。ofstream fout;

      这就可以了,不过你要打开一个文件的话, 必须像这样调用ofstream::open()。

    fout.open("output.txt");

      你也可以把文件名作为构造参数来打开一个文件.

    ofstream fout("output.txt");

      这是我们使用的方法, 因为这样创建和打开一个文件看起来更简单. 顺便说一句, 如果你要打开的文件不存在,它会为你创建一个, 所以不用担心文件创建的问题. 现在就输出到文件,看起来和"cout"的操作很像。 对不了解控制台输出"cout"的人, 这里有个例子。

    int num = 150;
    char name[] = "John Doe";
    fout << "Here is a number: " << num << "\n";
    fout << "Now here is a string: " << name << "\n";

      现在保存文件,你必须关闭文件,或者回写文件缓冲. 文件关闭之后就不能再操作了, 所以只有在你不再操作这个文件的时候才调用它,它会自动保存文件。 回写缓冲区会在保持文件打开的情况下保存文件, 所以只要有必要就使用它。回写看起来像另一次输出, 然后调用方法关闭。像这样:

    fout << flush; fout.close();

       现在你用文本编辑器打开文件,内容看起来是这样:

      Here is a number: 150 Now here is a string: John Doe

      很简单吧! 现在继续文件输入, 需要一点技巧, 所以先确认你已经明白了流操作,对 "<<" 和">>" 比较熟悉了, 因为你接下来还要用到他们。继续…

      二、ASCII 输入

      输入和"cin" 流很像. 和刚刚讨论的输出流很像, 但你要考虑几件事情。在我们开始复杂的内容之前, 先看一个文本:

      12 GameDev 15.45 L This is really awesome!

      为了打开这个文件,你必须创建一个in-stream对象,?像这样。

    ifstream fin("input.txt");

      现在读入前四行. 你还记得怎么用"<<" 操作符往流里插入变量和符号吧?好,?在 "<<" (插入)?操作符之后,是">>" (提取) 操作符. 使用方法是一样的. 看这个代码片段.

    int number;
    float real;
    char letter, word[8];
    fin >> number; fin >> word; fin >> real; fin >> letter;

      也可以把这四行读取文件的代码写为更简单的一行。

    fin >> number >> word >> real >> letter;

      它是如何运作的呢? 文件的每个空白之后, ">>" 操作符会停止读取内容, 直到遇到另一个>>操作符. 因为我们读取的每一行都被换行符分割开(是空白字符), ">>" 操作符只把这一行的内容读入变量。这就是这个代码也能正常工作的原因。但是,可别忘了文件的最后一行。

      This is really awesome!

      如果你想把整行读入一个char数组, 我们没办法用">>"?操作符,因为每个单词之间的空格(空白字符)会中止文件的读取。为了验证:

    char sentence[101]; fin >> sentence;

      我们想包含整个句子, "This is really awesome!" 但是因为空白, 现在它只包含了"This". 很明显, 肯定有读取整行的方法, 它就是getline()。这就是我们要做的。

    fin.getline(sentence, 100);

      这是函数参数. 第一个参数显然是用来接受的char数组. 第二个参数是在遇到换行符之前,数组允许接受的最大元素数量. 现在我们得到了想要的结果:“This is really awesome!”。

      你应该已经知道如何读取和写入ASCII文件了。但我们还不能罢休,因为二进制文件还在等着我们。

      三、二进制 输入输出

      二进制文件会复杂一点, 但还是很简单的。首先你要注意我们不再使用插入和提取操作符(译者注:<< 和 >> 操作符). 你可以这么做,但它不会用二进制方式读写。你必须使用read() 和write() 方法读取和写入二进制文件. 创建一个二进制文件, 看下一行。

    ofstream fout("file.dat", ios::binary);

      这会以二进制方式打开文件, 而不是默认的ASCII模式。首先从写入文件开始。函数write() 有两个参数。 第一个是指向对象的char类型的指针, 第二个是对象的大小(译者注:字节数)。 为了说明,看例子。

    int number = 30; fout.write((char *)(&number), sizeof(number));

      第一个参数写做"(char *)(&number)". 这是把一个整型变量转为char *指针。如果你不理解,可以立刻翻阅C++的书籍,如果有必要的话。第二个参数写作"sizeof(number)". sizeof() 返回对象大小的字节数. 就是这样!

      二进制文件最好的地方是可以在一行把一个结构写入文件。 如果说,你的结构有12个不同的成员。 用ASCII?文件,你不得不每次一条的写入所有成员。 但二进制文件替你做好了。 看这个。

    struct OBJECT { int number; char letter; } obj;
    obj.number = 15;
    obj.letter = ‘M’;
    fout.write((char *)(&obj), sizeof(obj));

      这样就写入了整个结构! 接下来是输入. 输入也很简单,因为read()?函数的参数和 write()是完全一样的, 使用方法也相同。

    ifstream fin("file.dat", ios::binary); fin.read((char *)(&obj), sizeof(obj));

      我不多解释用法, 因为它和write()是完全相同的。二进制文件比ASCII文件简单, 但有个缺点是无法用文本编辑器编辑。 接着, 我解释一下ifstream 和ofstream 对象的其他一些方法作为结束.

      四、更多方法

      我已经解释了ASCII文件和二进制文件, 这里是一些没有提及的底层方法。

      检查文件

      你已经学会了open() 和close() 方法, 不过这里还有其它你可能用到的方法。

      方法good() 返回一个布尔值,表示文件打开是否正确。

      类似的,bad() 返回一个布尔值表示文件打开是否错误。 如果出错,就不要继续进一步的操作了。

      最后一个检查的方法是fail(), 和bad()有点相似, 但没那么严重。

      读文件

      方法get() 每次返回一个字符。

      方法ignore(int,char) 跳过一定数量的某个字符, 但你必须传给它两个参数。第一个是需要跳过的字符数。 第二个是一个字符, 当遇到的时候就会停止。 例子,

    fin.ignore(100, ‘\n’);

      会跳过100个字符,或者不足100的时候,跳过所有之前的字符,包括 ‘\n’。

      方法peek() 返回文件中的下一个字符, 但并不实际读取它。所以如果你用peek() 查看下一个字符, 用get() 在peek()之后读取,会得到同一个字符, 然后移动文件计数器。

      方法putback(char) 输入字符, 一次一个, 到流中。我没有见到过它的使用,但这个函数确实存在。

      写文件

      只有一个你可能会关注的方法.?那就是 put(char), 它每次向输出流中写入一个字符。

      打开文件

      当我们用这样的语法打开二进制文件:

    ofstream fout("file.dat", ios::binary);

      "ios::binary"是你提供的打开选项的额外标志. 默认的, 文件以ASCII方式打开, 不存在则创建, 存在就覆盖. 这里有些额外的标志用来改变选项。

      ios::app 添加到文件尾
      ios::ate 把文件标志放在末尾而非起始。
      ios::trunc 默认. 截断并覆写文件。
      ios::nocreate 文件不存在也不创建。
      ios::noreplace 文件存在则失败。

      文件状态

      我用过的唯一一个状态函数是eof(), 它返回是否标志已经到了文件末尾。 我主要用在循环中。 例如, 这个代码断统计小写‘e’ 在文件中出现的次数。

    ifstream fin("file.txt");
    char ch; int counter;
    while (!fin.eof()) {
    ch = fin.get();
    if (ch == ‘e’) counter++;
    }
    fin.close();

      我从未用过这里没有提到的其他方法。 还有很多方法,但是他们很少被使用。参考C++书籍或者文件流的帮助文档来了解其他的方法。

      结论

      你应该已经掌握了如何使用ASCII文件和二进制文件。有很多方法可以帮你实现输入输出,尽管很少有人使用他们。我知道很多人不熟悉文件I/O操作,我希望这篇文章对你有所帮助。 每个人都应该知道. 文件I/O还有很多显而易见的方法,?例如包含文件 <stdio.h>. 我更喜欢用流是因为他们更简单。 祝所有读了这篇文章的人好运, 也许以后我还会为你们写些东西。

    展开全文
  • 实例解析文本文件二进制文件

    千次阅读 2013-05-07 14:36:53
    在使用程序处理文件的时候,总有两个概念是我们无法避开的:二进制文件和文本文件。究竟什么是文本文件,什么是二进制文件,说起来虽然很简单,但能否真正理解其差别并灵活应用在程序之中,却是另外一回事。在这篇...
  • 首先要明白一点,就是无论你用... 用二进制模式打开一个文件的时候,文件本身的内容你编写程序时用函数读到的内容完全相同(或者说和磁盘上的内容完全相同)。  但是如果用了文本模式,那么操作系统在将文件
  • 文本文件二进制文件区别

    千次阅读 2018-11-15 13:50:18
    ... 1)文本文件:这类文件以文本的ASCII码...2)二进制文件:这类文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们,只有通过相应的软件才能将其显示出来。二进制文件一般是可执行程序、图形、图像...
  • 文本文件文本文件是一种计算机文件,它是一种典型的顺序文件,其文件的逻辑结构又属于流式文件。 特别的是,文本文件是指以ASCII码方式(也称文本方式)存储的文件,更确切地说,英文、数字等字符存储的是ASCII码...
  • 1、二进制文件是把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放,也就是说存放的是数据的原...首先要考虑的问题并不是你要选择用二进制文件还是文本文件来进行存储,而是首先得考虑你要存储的数据是...
  • 二进制文件

    2015-05-22 21:02:52
    本质上是文本文件是把文件信息先转化成以字符编码的ascii码,再存储ascii的二进制代码。而二进制文件是直接把文件信息编码成二进制...稍微了解C程序设计的人都知道,文本文件和二进制文件在计算机上面都是以0,1存储的,
  • C语言读取文件文本模式和二进制模式的区别

    千次阅读 多人点赞 2016-07-22 16:14:58
    二进制存储和文本存储完全不相同?对于纯文本必须使用文本模式?对于纯数字必须使用二进制模式?如果你对这些有疑惑,这篇文章适合你,如果你是来看函数时如何使用的,可能你要另寻他处了。 二、明白关键一点  任何...
  • 关于二进制文件读写。
  • [Matlab+C/C++] 读写二进制文件

    千次阅读 2016-03-08 01:08:00
    在处理某些数据的时候,可能涉及到文件的读写,如果用MATLAB存储为mat文件,那么其它程序读取这种数据就变得困难了。如果将数据存为文本文件,文件的解析...本文就介绍一下如何使用MATLABC/C++对二进制文件进行读写。
  • 二进制文件读写

    2012-11-04 20:09:57
     我一直以为自己很熟悉如何使用C/C++中的二进制文件,可今天测试的时候突然发现程序生成的二进制文件和文本文件一样。比如:  FILE* fp = fopen("binary","wb");  //FILE* fp = fopen("character.txt","w")...
  •  用二进制模式打开一个文件的时候,文件本身的内容你编写程序时用函数读到的内容完全相同(或者说和磁盘上的内容完全相同)。 但是如果用了文本模式,那么操作系统在将文件内容传给上层程序(库函数,...
  • open语句对文本和二进制文件的读写

    千次阅读 2015-09-06 10:54:00
    文本文件的操作此种方式是以行为单位进行读取的基本单位,主要应用的方法函数有Open,Close,Line Input,FreeFile,EOF等。先简述其功能然后结合代码示例进行说明。Open:顾名思义,它的作用是打开文件,换而言之...
  • 二进制文件格式设计

    千次阅读 2017-08-09 22:31:06
    ...应该优先考虑文本格式,文本格式容易测试编辑。更应该优先考虑通用的文本格式,比如 XML, JSON, Lua 等等。这些通用的文本格式已经存在大量的工具库,可以省下很多功夫。 文本格式读
  • C++二进制文件读写

    千次阅读 2014-02-13 14:16:42
    我一直以为自己很熟悉如何使用C/C++中的二进制文件,可今天测试的时候突然发现程序生成的二进制文件和文本文件一样。 比如: FILE* fp = fopen("binary","wb"); //FILE* fp = fopen("character.txt","w");...
  • Linux二进制文件操作工具

    千次阅读 2020-05-19 12:09:48
    可以利用filesize来简单直接的查看二进制文件的细节。 1.1 file 命令行工具file可以用于查看几乎任何类型文件的详细信息。如 1.2 size 命令行工具size能够快速地获取ELF节的字节长度。 2 详细信息分析工具 可以...
  • linux下的二进制文件比较命令cmp

    万次阅读 2016-10-12 14:09:41
    cmp 比较二进制文件内容差异 功能:cmp 命令逐字节比较两个文件内容。如果两个文件内容完全,则cmp命令不...一般用cmp命令比较二进制文件,diff命令比较文本文件。 语法:cmp [选项] [文件1] [文件2] -l
  • Qt 学习 之 二进制文件读写

    万次阅读 2015-06-11 16:59:26
    同时,Qt 还提供了更高一级的操作:用于二进制的流QDataStream用于文本流的QTextStream。本节,我们将讲解有关QDataStream的使用以及一些技巧。下一章则是QTextStream的相关内容。QDataStream提供了基于Q
  • 换句话说,在操作系统内部,unix like 系统仅有一种文件结构,文本二进制实现是相同的。 因此使用fopen , ”r ” ” rb ”, “w” “wb ”,是一样的。 而给人看的部分,分成了文本视觉与二进制视觉
  • 处理二进制文件: 使用read获取头部44个字节: b表示二进制模式 struct .unpack( '数据类型' , '待解析二进制字符串' ) 声道数, 采样频率, 采样用多少个比特编码 对于...
  • Linux下的二进制文件比较工具

    千次阅读 2018-11-14 13:58:23
    Linux下的二进制文件比较工具

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 114,416
精华内容 45,766
关键字:

二进制文件和文本文件相同点