http://www.iteedu.com/plang/ccpp/cppdxjch2b/111.php

C++语言把每一个文件都看成一个有序的字节流(见图14.2),每一个文件或者以文件结束符(end-of-file marker)结束,或者在特定的字节号处结束(结束文件的特定的字节号记录在由系统维护和管理的数据结构中)。当打开一个文件时,该文件就和某个流关联起来。第11章曾介绍过cin、cout、cerr和clog这4个对象会自动生成。与这些对象相关联的流提供程序与特定文件或设备之间的通信通道。例如.cin对象(标准输入流对象)使程序能从键盘输入数据,cout对象(标准输出流对象)使程序能向屏幕输出数据,cerr和clog对象(标准错误流对象)使程序能向屏幕输出错误消息。

图14.2 C++把文件看成n个字节

要在C++中进行文件处理,就要包括头文件<iostream.h>和<fstream.h>。<fstream.h>头文件包括流类ifstream(从文件输入)、ofstream(向文件输出)和fstream(从文件输入,输出)的定义。生成这些流类的对象即可打开文件。这些流类分别从istream、ostream和iostream类派生(即继承它们的功能)。这样,第11章“C++输入,输出流”中介绍的成员函数、运算符和流操纵算子也可用于文件流。I/O类的继承关系见图14.3。

14.4 建立顺序访问文件

因为C++把文件看着是无结构的字节流,所以记录等等的说法在C++文件中是不存在的。为此,程序员必须提供满足特定应用程序要求的文件结构。下例说明了程序员是怎样给文件强加一个记录结构。先列出程序,然后再分析细节。

图14.4中的程序建立了一个简单的顺序访问文件,该文件可用在应收账目管理系统中跟踪公司借贷客户的欠款数目。程序能够获取每一个客户的账号、客户名和对客户的结算额。一个客户的数据就构成了该客户的记录。账号在应用程序中用作记录关键字,文件按账号顺序建立和维护。范例程序假定用户是按账号顺序键人记录的(为了让用户按任意顺序键入记录,完善的应收账目管理系统应该具备排序能力)。然后把键入的记录保存并写入文件。

  1. // Fig. 14.4; fig14_04.cpp
  2. // Create a sequential file
  3. #include <iostream.h>
  4. #include <fstream.h>
  5. #include <stdlib.h>
  6. int main()
  7. {
  8. // ofstream constructor opens file
  9. ofstream outClientFile( "clients.dat", ios::out );
  10. if ( !outClientFile ) { // overloaded ! operator
  11. cerr << "File could not be opened" << endl;
  12. exit( 1 ); // prototype in stdlib.h
  13. }
  14. cout << "Enter the account, name, and balance.\n"
  15. << "Enter end-of-file to end input.\n? ";
  16. int account;
  17. char name[ 30 ];
  18. float balance;
  19. while (cin >> account >> name >> balance ) {
  20. outClientFile << account << ' ' << name
  21. << ' ' << balance << '\n';
  22. cout << "? ";
  23. }
  24. return 0; // ofstream destructor closes file
  25. }
  1. 输出结果:
  2. Enter the account, name, and balance.
  3. Enter end-of-file to end input.
  4. ? 100 Jones 24.98
  5. ? 200 Doe 345.67
  6. ? 300 White 0
  7. ? 400 Stone -42.16
  8. ? 500 Rich 224.62
  9. ? ^z

图 14.4 建立顺序文件

现在我们来研究这个程序。前面曾介绍过,文件通过建立ifstream、ofstream或fstream流类的对象而打开。图14.4中,要打开文件以便输出,因此生成ofstream对象。向对象构造函数传入两个参数——文件名和文件打开方式。对于ostream对象,文件打开方式可以是ios::out(将数据输出到文件)或ios::app(将数据添加到文件末尾,而不修改文件中现有的数据)。现有文件用ios::out打开时会截尾,即文件中的所有数据均删除。如果指定文件还不存在,则用该文件名生成这个文件。下列声明(第10行):

ofstream outClientFile(“clients.dat”.ios::out);

生成ofstream对象outClientfile,与打开输出的文件clients.dat相关联。参数"clients.dat"和ios::out传入ofstream构造函数,该函数打开文件,从而建立与文件的通信线路。默认情况下,打开ofstream对象以便输出,因此下列语句:

ofstream outClientFile (”clients.dat”);

也可以打开clients.dat进行输出。图14.5列出了文件打开方式。

常见编程错误14.1

打开一个用户想保留数据的现有文件进行输出(ios::out方式)。这种操作会删除文件的内容而不会给予警告。

常见编程错误14. 2

用错误的ofstream对象指明一个文件。

也可以生成ofstream对象而不打开特定文件,可以在后面再将文件与对象相连接。例如,下列声明:

ofstream outClientFile;

生成以ofstram对象outClientFile。ofstream成员函数open打开文件并将其与现有ofstream对象相连接,如下所示:

outClientFile open(”clients.dat”,ios::out);

  1. ------------------------------------------------------------------------------------------
  2. 文件打开方式 说明
  3. ------------------------------------------------------------------------------------------
  4. ios::app 将所有输出写入文件末尾
  5. ios::ate 打开文件以便输出,井移到文件末尾(通常用于添加数据)数据可以写入
  6. 文件中的任何地方
  7. ios::in 打开文件以便输入
  8. ios::out 打开文件以便输出
  9. ios::trunc 删除文件现有内容(是ios::out的默认操作)
  10. ios::nocreate 如果文件不存在,则文件打开失败
  11. ios::noreplace 如果文件存在,则文件打开失败
  12. ------------------------------------------------------------------------------------------

图14. 5 文件打开方式

常见编程错误 14. 3

在引用文件之前忘记打开该文件。

生成ofstream对象并准备打开时,程序测试打开操作是否成功。下列if结构中的操作(第12行到第15行):

  1. if ( !outClientFile ) {
  2. cerr << "File could not be opened" << endl;
  3. exit(1);
  4. }

用重载的ios运算符成员函数operator!确定打开操作是否成功。如果open操作的流将failbit或badbit设置,则这个条件返回非0值(true)。可能的错误是试图打开读取不存在的文件、试图打开读取没有权限的文件或试图打开文件以便写人而磁盘空间不足。

如果条件表示打开操作不成功.则输出错误消息“File could not be opened",并调用函数exit结束程序,exit的参数返回到调用该程序的环境中,参数0表示程序正常终止.任何其他值表示程序因某个错误而终止。exit返回的值让调用环境(通常是操作系统)对错误做出相应的响应。

另一个重载的ios运算符成员函数operator void*将流变成指针,使其测试为0(空指针)或非0(任何其他指针值)。如果failbit或badbit(见第11章)对流进行设置,则返回0(false)。下列while首部的条件自动调用operator void*成员函数:

while (cin >> account >> name >> balance )

只要cin的failbit和badbit都没有设置,则条件保持true。输入文件结束符设置cin的failbit。operator void*函数可以测试输入对象的文件结束符,而不必对输入对象显式调用eof成员函数。

如果文件打开成功,则程序开始处理数据。下列语句(第17行和第18行)提示用户对每个记录输入不同域,或在数据输入完成时输入文件结束符:

  1. cout << "Enter the account, name, and balance. "
  2.  
  3. << "Enter EOF to and input. ";

图14. 6列出了不同计算机系统中文件结束符的键盘组合。

  1. ---------------------------------------------------
  2. 计算机系统 组合键
  3. ---------------------------------------------------
  4. UNIX系统 d
  5. IBM PC及其兼容机 z
  6. Macintosh d
  7. VAX(VMS) z
  8. ---------------------------------------------------

图14.6各种流行的计算机系统中的文件结束组合键

下列语句(第24行):

while (cin >> account >> name >> balance )

输入每组数据并确定是否输人了文件结束符。输入文件结束符或不合法数据时,cin的流读取运算符 >>返回0(通常这个流读取运算符>>返回cin),while结构终止。用户输入文件结束符告诉程序没有更多要处理的数据。当用户输入文件结束符组合键时,设置文件结束符。只要没有输入文件结束符,while结构就一直循环。

第25行和第26行:

  1. outClientFile << account << ' ' << name
  2.  
  3. << ' ' << balance << ' ';

用流插人运算符<<和程序开头与文件相关联的outClientFile对象将一组数据写入文件”clients.dat"。

可以用读取文件的程序取得这些数据(见14.5节)。注意图14.4中生成的文件是文本文件,可以用任何文本编辑器读取。

输人文件结束符后,main终止,使得outClientFile对象删除,从而调用其析构函数,关闭文件

clients.dat。程序员可以用成员函数close显式关闭ofstream对象,如下所示:

outClientFile.close();

性能提示14. 1

程序不再引用的文件应立即显式关闭.这样可以减少程序继续执行时占用的资源。这种方法还可以提高程序的清晰性。

在图14.4的执行范例中,用户输人了五条记录.然后键入了表示数据输入结束的文件结束符(IBM PC兼容机的屏幕上显示^z)。输出结果的对话窗口中没有说明这些记录究竟是怎样在文件中组织。为了验证文件的建立是成功的,下一节介绍了读取和打印该文件的程序。

【转载】C++的文件和流的更多相关文章

  1. 【转载】java文件路径问题及getResource和getClassLoader().getResource的区别

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012572955/article/details/52880520我们经常在java的io操作中读 ...

  2. C#文件与流(FileStream、StreamWriter 、StreamReader 、File、FileInfo、Directory、directoryInfo、Path、Encoding)

    (FileStream.StreamWriter .StreamReader .File.FileInfo.Directory.DirectoryInfo.Path.Encoding)     C#文 ...

  3. Java - 文件(IO流)

    Java - 文件 (IO)   流的分类:     > 文件流:FileInputStream | FileOutputStream | FileReader | FileWriter     ...

  4. Java IO 文件与流基础

    Java IO 文件与流基础 @author ixenos 摘要:创建文件.文件过滤.流分类.流结构.常见流.文件流.字节数组流(缓冲区) 如何创建一个文件 #当我们调用File类的构造器时,仅仅是在 ...

  5. c# 文件与流

    1.创建和删除目录 在c#中涉及到输入.输出(i/o)相关操作的API都被放在System.IO命名空间下,或者子命令System.IO.IsolatedStoorage中.对目录进行操作可以使用Di ...

  6. C++ 文件和流

    到目前为止,我们已经使用了 iostream 标准库,它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流. 本教程介绍如何从文件读取流和向文件写入流.这就需要用到 C++ ...

  7. netframework转core时文件响应流问题

    做将framework webapi项目转成netcore平台上的webapi项目时,发现原来的返回文件响应流在netcore平台下失效.代码如下,返回pdf文件响应流,供前端显示 /// <s ...

  8. (C/C++学习笔记) 二十. 文件和流

    二十. 文件和流 ● 文件的概念 文件(file) 一. C/C++语言将文件作为字节序列(sequence of characters)来对待,但从编码角度,或说从对字节信息的解释来看,文件分为:文 ...

  9. 进阶系列(4)—— C#文件与流

    一. 驱动器 在Windows操作系统中,存储介质统称为驱动器,硬盘由于可以划分为多个区域,每一个区域称为一个驱动器..NET Framew   ork提供DriveInfo类和 DriveType枚 ...

随机推荐

  1. 一个IO的传奇一生 系列 存储之道

    http://alanwu.blog.51cto.com/3652632/1286553

  2. 读写应用程序数据-NSUserDefault、对象归档(NSKeyedArchiver)、文件操作

    ios中数据持久化存储方式一般有5种:NSUserDefault.对象归档(NSKeyedArchiver).文件操作.数据库存储(SQLite3).CoreData. 1.NSUserDefault ...

  3. ajax技术的基本概述

    大家都知道ajax并非一种新的技术,而是几种原有技术的结合体.它由下列技术组合而成. 1.使用CSS和XHTML来表示. 2. 使用DOM模型来交互和动态显示. 3.使用XMLHttpRequest来 ...

  4. [Form Builder]NAME_IN()与COPY()

    NAME_IN和COPY实际是间接引用,类似指针传递,而不是值传递... IF :VAR1 IS NULL ...  direct referenceIF NAME_IN ( :VAR1 ) IS N ...

  5. Nginx高性能服务器安装、配置、运维 (4) —— Nginx服务、架构及其信号

    五.Nginx服务.架构及其信号 (1)Nginx服务的查看 1.netstat -antp 查看Nginx是否在80端口运行: 2.ps aux|grep nginx 查看nginx相关进程: 发现 ...

  6. visio篇章--1

    因为要做需求规格说明书的需要,所以学着用visio.发现visio中其实有很多东西的.我昨晚是用它来画ER图.不画不知道,花了之后才发现有很多窍门在里面.不说废话.我列举一下应该要的东西 1.百度链接 ...

  7. WildFly 9.0.2 + SQLServer + BIRT + JNDI 处理BIRT报表发布时数据源的修改

    一.前提需求说明: 最近在做项目的时候使用jboss WildFly发布BIRT报表,在报表中我是直接添加的JDBC数据源,通过Database URL .用户名和密码连接数据库.后来在部署到正式和测 ...

  8. _In_ 是什么意思

    函数参数类型前 _In_代表什么     在visual C++中属于SAL批注,是为了编译系统在分析代码时发现缺陷用的   表示是一个输入参数.可以定义一个_In_的宏,这个宏什么都不做, 就是形如 ...

  9. 使用PDO连接多种数据库

    在PHP 5之前,想要连接MySQL数据库就需要使用mysql或mysqli等一系列函数来操作数据库.例如,我们使用mysql系列数据库函数进行查询操作,对应的示例代码如下: <?php //创 ...

  10. 基于mod_proxy+Apache 2.2.16+Tomcat 7的负载均衡与集群配置

    第一章. 背景简介 对于大多数企业应用,都希望能做到7*24小时不间断运行.要保持如此高的可用性并非易事,比较常见的做法是将系统部署到多台机器上,每台机器都对外提供同样的功能,这就是集群.系统变为集群 ...