📄 fil_2309.htm
字号:
<HTML><HEAD><TITLE>2.5 File Input/Output</TITLE></HEAD><BODY><A HREF="ug2.htm"><IMG SRC="images/banner.gif"></A><BR><A HREF="err_7848.htm"><IMG SRC="images/prev.gif"></A><A HREF="booktoc2.htm"><IMG SRC="images/toc.gif"></A><A HREF="inm_4073.htm"><IMG SRC="images/next.gif"></A><BR><STRONG>Click on the banner to return to the user guide home page.</STRONG><H2>2.5 File Input/Output</H2><P>File streams allow input and output to files. Unlike the C stdio functions for file I/O, however, file streams follow Stroustrup's idiom: "Resource acquisition is initialization."<A HREF="endnote2.htm#fn25">[25]</A> In other words, file streams provide an advantage in that you can open a file on construction of a stream, and the file will be closed automatically on destruction of the stream. Consider the following code:</P><PRE>void use_file(const char* fileName){ FILE* f = fopen("fileName", "w"); // use file fclose(f);}</PRE><P>If an exception is thrown while the file is in use here, the file will never be closed. With a file stream, however, the file will be closed whenever the file stream goes out of scope, as in the following example:</P><PRE>void use_file(const char* fileName){ ofstream f("fileName"); // use file}</PRE><P>Here the file will be closed even if an exception occurs during use of the open file.</P><P>There are three class templates that implement file streams: <B><I><B><I>basic_ifstream <charT,traits></I></B></B></I>,<B><I><B><I> basic_ofstream <charT,traits></I></B></B></I>, and <B><I><B><I>basic_fstream <charT,traits></I></B></B></I>. These templates are derived from the stream base class <B><I><B><I>basic_ios <charT, traits></I></B></B></I>. Therefore, they inherit all the functions for formatted input and output described in <A HREF="for_5394.htm">Section 2.3</A>, as well as the stream state. They also have functions for opening and closing files, and a constructor that allows opening a file and connecting it to the stream. For convenience, there are the regular typedefs <SAMP>ifstream</SAMP>, <SAMP>ofstream</SAMP>, and <SAMP>fstream</SAMP>, with <SAMP>wifstream</SAMP>, <SAMP>wofstream</SAMP>, and <SAMP>wfstream</SAMP> for the respective tiny and wide character file streams.</P><P>The buffering is done through a specialized stream buffer class, <B><I><B><I>basic_filebuf <charT,traits></I></B></B></I>.</P><A NAME="2.5.1"><H3>2.5.1 The Difference between Predefined File Streams (cin, cout, cerr, and clog) and File Streams</H3></A><P>The main differences between a predefined standard stream and a file stream are:</P><UL><LI><P>A file stream needs to be connected to a file before it can be used. The predefined streams can be used right away, even in static constructors that are executed before the <SAMP>main()</SAMP> function is called.</P></LI><LI><P>You can reposition a file stream to arbitrary file positions. This usually does not make any sense with the predefined streams, as they are connected to the terminal by default.</P></LI></UL><A NAME="2.5.2"><H3>2.5.2 Code Conversion in Wide Character Streams</H3></A><P>In a large character set environment, a file is assumed to contain multibyte characters. To provide the contents of a such a file as a wide character sequence for internal processing, <SAMP>wifstream</SAMP> and <SAMP>wofstream</SAMP> perform corresponding conversions. The actual conversion is delegated to the file buffer, which relays the task to the imbued locale's code conversion facet.</P><A NAME="2.5.3"><H3>2.5.3 File Streams</H3></A><A NAME="2.5.3.1"><H4>2.5.3.1 Creating and Opening File Stream Objects</H4></A><P>There are two ways to create a file stream: you can create an empty file stream, open a file, and connect it to the stream later on; or you can open the file and connect it to a stream at construction time. These two procedures are demonstrated in the two following examples, respectively:</FN><PRE>ifstream file; \\1_;file.open(argv[1]); \\2if (!file) // error: unable to open file for input</PRE><P>or:</P><PRE>ifstream source("src.cpp"); \\3if (!source) // error: unable to open src.cpp for input</PRE><TABLE CELLPADDING="3"><TR VALIGN="top"><TD>//1</TD><TD>A file stream is created that is not connected to any file. Any operation on the file stream will fail.</TD></TR><TR VALIGN="top"><TD>//2</TD><TD>Here a file is opened and connected to the file stream. If the file cannot be opened, <SAMP>ios_base::failbit</SAMP> will be set; otherwise, the file stream is now ready for use.</TD></TR><TR VALIGN="top"><TD>//3</TD><TD>Here the file is both opened and connected to the stream.</TD></TR></TABLE><A NAME="2.5.3.2"><H4>2.5.3.2 Checking a File Stream's Status</H4></A><P>Generally you can check whether the attempt to open a file was successful by examining the stream state afterwards; <SAMP>failbit</SAMP> will be set in case of failure. </P><P>There is also a function called <SAMP>is_open()</SAMP>that indicates whether a file stream is connected to an open file. This function does <I>not</I> mean that a previous call to <SAMP>open()</SAMP> was successful. To understand the subtle difference, consider the case of a file stream that is already connected to a file. Any subsequent call to <SAMP>open()</SAMP> will fail, but <SAMP>is_open()</SAMP> will still return true, as shown in the following code:</P><PRE>void main(int argc, char* argv[]){ if (argc > 2) { ofstream fil; //1 fil.open(argv[1]); // ... fil.open(argv[2]); //2 if (fil.fail()) //3 { // open failed } if (fil.is_open()) //4 { // connected to an open file }}</PRE><TABLE CELLPADDING="3"><TR VALIGN="top"><TD>//1</TD><TD>Open a file and connect the file stream to it.</TD></TR><TR VALIGN="top"><TD>//2</TD><TD>Any subsequent open on this stream will fail.</TD></TR><TR VALIGN="top"><TD>//3</TD><TD>Hence the <SAMP>failbit</SAMP> will be set.</TD></TR><TR VALIGN="top"><TD>//4</TD><TD>However, <SAMP>is_open()</SAMP> still returns true, because the file stream still is connected to an open file.</TD></TR></TABLE><A NAME="2.5.3.3"><H4>2.5.3.3 Closing a File Stream</H4></A><P>In the example above, it would be advisable to close the file stream before you try to connect it to another file. This is done implicitly by the file streams destructor in the following:</P><PRE>void main(int argc, char* argv[]){ if (argc > 2) { ofstream fil; fil.open(argv[1]); // ... } //1 { ofstream fil; fil.open(argv[2]); // ... }}</PRE><TABLE CELLPADDING="3"><TR VALIGN="top"><TD>//1</TD><TD>Here the file stream <SAMP>fil</SAMP> goes out of scope and the file it is connected to will be closed automatically.</TD></TR></TABLE><P>You can explicitly close the connected file. The file stream is then empty, until it is reconnected to another file:</P><PRE>ifstream f; //1for (int i=1; i<argc; ++i){ f.open(argv[i]); //2 if (f) //3 { process(f); //4 f.close(); //5 } else cerr << "file " << argv[i] << " cannot be opened.\n";}</PRE><TABLE CELLPADDING="3"><TR VALIGN="top"><TD>//1</TD><TD>An empty file stream is created.</TD></TR><TR VALIGN="top"><TD>//2</TD><TD>A file is opened and connected to the file stream.</TD></TR><TR VALIGN="top"><TD>//3</TD><TD>Here we check whether the file was successfully opened. If the file could not be opened, the <SAMP>failbit</SAMP> would be set.</TD></TR><TR VALIGN="top"><TD>//4</TD><TD>Now the file stream is usable, and the file's content can be read and processed.</TD></TR><TR VALIGN="top"><TD>//5</TD><TD>Close the file again. The file stream is empty again.</TD></TR></TABLE><A NAME="2.5.4"><H3>2.5.4 The Open Mode</H3></A><P>There may be times when you want to modify the way in which a file is opened or used in a program. For example, in some cases it is desirable that writes append to the end of a file rather than overwriting the existing values. The file stream constructor takes a second argument, the <I>open mode</I>, that allows such variations to be specified. Here is an example:</P><PRE>fstream Str("inout.txt", ios_base::in|ios_base::out|ios_base::app);</PRE><A NAME="2.5.4.1"><H4>2.5.4.1 The Open Mode Flags</H4></A><P>The open mode argument is of type <SAMP>ios_base::openmode</SAMP>, which is a bitmask type like the format flags and the stream state. The following bits are defined in Table 7:</P><H4>Table 7: Flag names and effects</H4><CENTER><TABLE BORDER CELLSPACING=3 CELLPADDING=3><TR VALIGN=top><TD><B>Flag Names</B><BR></TD><TD><B>Effects</B><BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::in</SAMP><BR></TD><TD>Open file for reading<BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::out</SAMP><BR></TD><TD>Open file for writing<BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::ate</SAMP><BR></TD><TD>Start position is at file end<BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::app</SAMP><BR></TD><TD>Append file; i.e., always writes to the end of the file<BR></TD></TR><TR VALIGN=top><TD><SAMP>ios_base::trunc</SAMP><BR></TD><TD>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -