目录

第1章读写文件    1

1.1 API    1

1.2 低级IO    1

1.2.1 文件序号    1

1.2.2 文本文件与二进制文件    1

1.3 流IO    2

1.4 Unicode    3

1.5 流IO、低级IO、API之间的关系    3

1.6 随机读写    4

1.7 C++IO流    4

1.8 MFC    4

1.8.1 CFile    4

1.8.2 CStdioFile    4

1.8.3 CArchive    4

1.9 总结    5

第1章读写文件

1.1 API

使用VC++读写文件,最直接、最高效的方法就是使用 Windows API,如:使用 CreateFile 打开文件,使用 WriteFile 写文件,使用 ReadFile 读文件……Windows 平台下,所有对文件的读写操作,最终都会调用这些 API 函数。使用 API 的效率最高,对文件读写的控制最强,缺点就是比较复杂,而且代码没有可移植性。

1.2 低级IO

为了方便移植 UNIX 的C代码,VC++的C运行时库实现了一套低级IO函数,如:_open、_write、_read……

1.2.1 文件序号

_open返回的是一个整数,MSDN上称其为文件句柄(file handle),这与CreateFile返回的文件句柄容易混淆。为此,本文称_open返回的为文件序号。

VC++中,系统预先打开了三个文件,其文件序号如下表所示

文件序号

说明

stdin

0

标准输入设备,一般就是键盘

stdout

1

标准输出设备,一般就是控制台

stderr

2

标准错误输出设备,一般就是控制台

也就是说,无需调用_open,可以直接调用_write(1,"abc",3);往控制台输出abc三个字符。

1.2.2 文本文件与二进制文件

读写二进制文件时,不会做任何处理,数据保持原样。写文本文件时,VC++会将换行符(即\n,0AH)替换为回车(即\r,0DH)和换行符;读文本文件时,VC++会将\r\n替换为\n,并且在读取到1AH时,认为文件结束。

_open函数里可以指定文件模式,

如:_open("c:\\1.txt",_O_RDONLY | _O_TEXT);     //文本模式

如:_open("c:\\1.txt",_O_RDONLY | _O_BINARY);     //二进制模式

如果_open函数里未指定 _O_TEXT 和 _O_BINARY,则以全局变量_fmode为准,如下面的代码将以文本模式打开文件。

_fmode = _O_TEXT;

_open("c:\\1.txt",_O_RDONLY);

假定c:\1.txt的内容如下:

1

2

3

\r

\n

4

5

6

\r

\n

执行如下代码:

int    n = _open("c:\\1.txt",_O_RDONLY | _O_BINARY);

char    str[128];

_read(n,str,128);

_close(n);

str的内容将是"123\r\n456\r\n"。将_O_BINARY替换为_O_TEXT,则str的内容将变为"123\n456\n"。可见\r\n如期的被替换为\n。不过,需要注意的是:将\r\n替换为\n是在第二个参数内进行的,如:将_read(n,str,128);替换为下面两行代码:

_read(n,str,4);    //读取到"123\r"

_read(n,str,4);    //读取到"\n456"

这个时候,\r\n就不会被替换为\n。这点要特别注意。

1.3 流IO

流IO函数有:fopen、fwrite、fread……它与低级IO最大的区别在于:低级IO无缓冲区,而流IO有缓冲区。如:同样的写文件,_write 会直接调用 WriteFile,而 fwrite 会将数据写入缓冲区,达到一定数量后,再调用 WriteFile 将缓冲区内的数据写入文件。显然,流IO将大大减少调用 API 函数的次数,因此理论上其效率会比较高。

使用setvbuf函数,可以对缓冲区的大小、行为进行设置。

VC++里,流IO由低级IO实现。即:fopen会调用_open,fwrite会调用_write,fgets会调用_read函数……

流IO最重大的意义在于:它是符合ANSI C 标准的一套函数,可移植性最高。

1.4 Unicode

Windows的API函数一般会分为两个版本,即处理ANSI字符串的窄字符版本,和处理Unicode字符串的宽字符版本。低级IO和流IO也有类似的宽字符版本函数,如:_wopen、_wfopen……

使用宽字符版本的IO函数之前,一定要调用setlocale(LC_ALL,""),设置 C 函数的代码页为系统默认的代码页,否则就有可能会出现乱码。

1.5 流IO、低级IO、API之间的关系

三者的关系如下图所示:流IO由低级IO实现,而低级IO由API实现。

函数_fileno可根据流IO的FILE*获得低级IO的文件序号;

函数_get_osfhandle可根据低级IO的文件序号获得API的文件句柄;

函数_open_osfhandle可根据API的文件句柄获得低级IO的文件序号;

函数_fdopen可根据低级IO的文件序号获得流IO的FILE*。

1.6 随机读写

随机读写是对文件读写的一种方式,具体表现为:

1、读或写时,会移动文件指针;

2、读、写操作交叉进行,如:读了几次后又写几次。

如果使用低级IO进行随机读写,读写函数的处理是比较简单的。反之,对于有缓冲区的流IO而言,随机读写反而可能会降低文件的读写效率。因为以上两个操作,将频繁的清空缓冲区、移动文件指针。可以说,在随机读写文件上,流IO并不比低级IO有优势。

1.7 C++IO流

C++的STL中,可以使用 fstream、ifstream、ofstream……对文件进行读写。它的内部使用了流IO。

1.8 MFC

1.8.1 CFile

CFile是低级IO的C++实现。它直接调用 API,主要用于读写二进制文件。

1.8.2 CStdioFile

CStdioFile用于读写文本文件,具体的就是读写一行行的文本。它内部调用了流IO。当以 Unicode 编译程序时,CStdioFile 将调用 Unicode 版本的流IO函数,此时一定要首先调用 setlocale(LC_ALL,"")。还需要说明的一点是:从 EVC3.0 至 VC2008,CStdioFile 都是无法正常运行在 Windows CE 平台上的。

1.8.3 CArchive

CArchive 主要用于串行化,它可以与 CFile 或 CMemFile 关联,然后通过<<和>>方便的实现变量的串行化和反串行化。

CArchive 与 CFile 关联,串行化时变量将保存至文件。

CArchive 与 CMemFile 关联,串行化时变量将保存至内存。

CArchive 与CSocketFile关联,串行化时变量将通过套接字传输到网络。

1.9 总结

如果使用C语言,可以选择使用API、低级IO、流IO。如果代码要移植到其它平台,建议使用流IO。如果使用C++语言,上述方法均可使用。

读写二进制文件相对比较容易,比较复杂的是读写文本文件。复杂在两个方面:

1、各个操作系统定义的行结束符不尽相同,如:Linux定义\r为行结束符,Mac定义\n为行结束符,Windows定义\r\n为行结束符。而且,还需要考虑各个操作系统之间的文件读写,如:Linux生成的文本文件在Windows下读取……

2、必须考虑多种编码。如:Windows平台下,文本文件分为四种格式:ANSI、UTF16LE、UTF16BE、UTF-8。VC++6.0只支持读写ANSI编码的文本文件。自VC++2005开始,fopen增加了对UTF16LE、UTF-8这两种编码的支持,不过这种支持不适用于 Windows CE 平台。

上述两个问题,最好的解决办法就是自行编写一个处理文本文件的C++类。

VC++读写文件的更多相关文章

  1. VC的文件操作

    各种关于文件的操作在程序设计中是十分常见,如果能对其各种操作都了如指掌,就可以根据实际情况找到最佳的解决方案,从而在较短的时间内编写出高效的代码,因而熟练的掌握文件操作是十分重要的.本文将对Visua ...

  2. Hyper-V无法文件拖拽解决方案~~~这次用一个取巧的方法架设一个FTP来访问某个磁盘,并方便的读写文件

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...

  3. 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库

    57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...

  4. Python读写文件

    Python读写文件1.open使用open打开文件后一定要记得调用文件对象的close()方法.比如可以用try/finally语句来确保最后能关闭文件. file_object = open('t ...

  5. php中并发读写文件冲突的解决方案

    在这里提供4种高并发读写文件的方案,各有优点,可以根据自己的情况解决php并发读写文件冲突的问题. 对于日IP不高或者说并发数不是很大的应用,一般不用考虑这些!用一般的文件操作方法完全没有问题.但如果 ...

  6. C#读写文件的方法汇总_C#教程_脚本之家

    C#读写文件的方法汇总_C#教程_脚本之家 http://www.jb51.net/article/34936.htm

  7. Inno Setup 如何读写文件

    软件安装的实质就是拷贝,对于简单的打包当然不需要考虑修改某(配置)文件.通过inno修改文件的目的在于把安装时相关信息写入文件中,提供其它应用的读取,而这些信息也只能在安装时才能确定,比如安装用户选择 ...

  8. java使用IO读写文件总结

    每次用到IO的读写文件都老忘记写法,都要翻过往笔记,今天总结下,省的以后老忘.java读写文件的IO流分两大类,字节流和字符流,基类分别是字符:Reader和Writer:字节:InputStream ...

  9. python读写文件时中文的转码问题

    读写文件都要将中文转为unicode字符. 读文件: u = unicode(s, 'gbk') 这里不能使用encode 写文件: u = encode('utf')

随机推荐

  1. 快速掌握RabbitMQ(三)——消息确认、持久化、优先级的C#实现

    1 消息确认 在一些场合,如转账.付费时每一条消息都必须保证成功的被处理.AMQP是金融级的消息队列协议,有很高的可靠性,这里介绍在使用RabbitMQ时怎么保证消息被成功处理的.消息确认可以分为两种 ...

  2. [Bzoj3205][Apio2013]机器人(斯坦纳树)(bfs)

    3205: [Apio2013]机器人 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 977  Solved: 230[Submit][Status] ...

  3. UVA11825 Hackers' Crackdown

    题目描述 PDF 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 3 2 1 2 2 0 2 2 0 1 4 1 1 1 0 1 3 1 2 0 输出样例#1: Case 1: 3 ...

  4. Codeforces 757 F Team Rocket Rises Again

    Discription It's the turn of the year, so Bash wants to send presents to his friends. There are n ci ...

  5. (入门SpringBoot)SpringBoot项目数据源以及整合mybatis(二)

    1.配置tomcat数据源: #   数据源基本配置spring.datasource.url=jdbc:mysql://localhost:3306/shoptest?useUnicode=true ...

  6. Ubuntu 16.04下更新Atom

    在Ubuntu下Atom好像不会自动更新,但是可以通过这些方法去实现: 1.安装插件:https://atom.io/packages/up2date 2.使用apt源更新: sudo apt-get ...

  7. 【Linux学习笔记】栈与函数调用惯例

    栈与函数调用惯例(又称调用约定)— 基础篇 记得一年半前参加百度的校招面试时,被问到函数调用惯例的问题.当时只是懂个大概,比如常见函数调用约定类型及对应的参数入栈顺序等.最近看书过程中,重新回顾了这些 ...

  8. git 更新远程分支

    使用git的时候,有时候会出现远端更新了一个分支,但是从本地想checkout一个远程分支时,会出现如下错误: fatal: git checkout: updating paths is incom ...

  9. SSH login without password

    SSH login without password Your aim You want to use Linux and OpenSSH to automize your tasks. Theref ...

  10. Cocos2d-x游戏《雷电大战》开源啦!要源代码要资源快快来~~

    写在前面的话:这是笔者开发的第二个小游戏<雷电大战>,之前就过这个游戏和<赵云要格斗>一样,终于将会开源. 因为自己的一些个人原因. 这个游戏还没有完毕.可是很多网友都过来寻求 ...