📄 ch07_01.htm
字号:
CLASS="indexterm"NAME="ch07-idx-1000009573-4"></A>access mode. To open <EMCLASS="emphasis">/tmp/log</EM> for writing and to associate it with the filehandle <CODECLASS="literal">LOGFILE</CODE>, say:</P><PRECLASS="programlisting">open(LOGFILE, "> /tmp/log") or die "Can't write /tmp/log: $!";</PRE><PCLASS="para">The three most common access modes are < for reading, > for overwriting, and >> for appending. The <CODECLASS="literal">open</CODE> function is discussed in more detail in <ACLASS="xref"HREF="ch07_02.htm"TITLE="Opening a File">Recipe 7.1</A>.</P><PCLASS="para">When opening a file or making virtually any other system call,[<ACLASS="footnote"HREF="#ch07-pgfId-1000008479">1</A>] checking the return value is indispensable. Not every <CODECLASS="literal">open</CODE> succeeds; not every file is readable; not every piece of data you <CODECLASS="literal">print</CODE> can reach its destination. Most programmers check <CODECLASS="literal">open</CODE>, <CODECLASS="literal">seek</CODE>, <CODECLASS="literal">tell</CODE>, and <CODECLASS="literal">close</CODE> in robust programs. You might also want to check other functions. The Perl documentation lists return values from all functions and operators. If a system call fails, it returns <CODECLASS="literal">undef</CODE>, except for <CODECLASS="literal">wait</CODE>, <CODECLASS="literal">waitpid </CODE>, and <CODECLASS="literal">syscall</CODE>, which return <CODECLASS="literal">-1</CODE> on failure. The system error message or number is available in the <CODECLASS="literal">$!</CODE> variable. This is often used in <CODECLASS="literal">die</CODE> or <CODECLASS="literal">warn</CODE> messages.</P><BLOCKQUOTECLASS="footnote"><DIVCLASS="footnote"><PCLASS="para"><ACLASS="footnote"NAME="ch07-pgfId-1000008479">[1]</A> The term <EMCLASS="emphasis">system call</EM> denotes a call into your operating system. It is unrelated to the C and Perl function that's actually named <CODECLASS="literal">system</CODE>.</P></DIV></BLOCKQUOTE><PCLASS="para">To read a record in Perl, use the <ACLASS="indexterm"NAME="ch07-idx-1000009574-0"></A><ACLASS="indexterm"NAME="ch07-idx-1000009574-1"></A>circumfix operator <CODECLASS="literal"><FILEHANDLE></CODE>, whose behavior is also available through the <CODECLASS="literal">readline</CODE> function. A record is normally a line, but you can change the record terminator, as detailed in <ACLASS="xref"HREF="ch08_01.htm"TITLE="File Contents">Chapter 8</A>. If <CODECLASS="literal">FILEHANDLE</CODE> is omitted, Perl opens and reads from the filenames in <CODECLASS="literal">@ARGV</CODE> or from STDIN if there aren't any. Customary and curious uses of this are described in <ACLASS="xref"HREF="ch07_08.htm"TITLE="Writing a Filter">Recipe 7.7</A>.</P><PCLASS="para">Abstractly, files are simply streams of bytes. Each filehandle has associated with it a number representing the current byte position in the file, returned by the <CODECLASS="literal">tell</CODE> function and set by the <CODECLASS="literal">seek</CODE> function. In <ACLASS="xref"HREF="ch07_11.htm"TITLE="Modifying a File in Place Without a Temporary File">Recipe 7.10</A>, we rewrite a file without closing and reopening by using <CODECLASS="literal">seek</CODE> to move back to the start, rewinding it.</P><PCLASS="para">When you no longer have use for a filehandle, <CODECLASS="literal">close</CODE> it. The <CODECLASS="literal">close</CODE> function takes a single filehandle and returns true if the filehandle could be successfully flushed and closed, false otherwise. You don't need to explicitly close every filehandle. When you open a filehandle that's already open, Perl implicitly closes it first. When your program exits, any open filehandles also get closed.</P><PCLASS="para">These implicit closes are for convenience, not stability, because they don't tell you whether the system call succeeded or failed. Not all closes succeed. Even a <CODECLASS="literal">close</CODE> on a read-only file can fail. For instance, you could lose access to the device because of a network outage. It's even more important to check the <CODECLASS="literal">close</CODE> if the file was opened for writing. Otherwise you wouldn't notice if the disk filled up.</P><PRECLASS="programlisting">close(FH) or die "FH didn't close: $!";</PRE><PCLASS="para">The prudent programmer even checks the <CODECLASS="literal">close</CODE> on standard output stream at the program's end, in case STDOUT was redirected from the command line the output filesystem filled up. Admittedly, your run-time system should take care of this for you, but it doesn't. <ACLASS="indexterm"NAME="ch07-idx-1000009572-0"></A><ACLASS="indexterm"NAME="ch07-idx-1000009572-1"></A></P><PCLASS="para">Checking standard error, though, is probably of dubious value. After all, if STDERR fails to close, what are you planning to do about it?</P><PCLASS="para"><ACLASS="indexterm"NAME="ch07-idx-1000009575-0"></A>STDOUT is the default destination for output from the <CODECLASS="literal">print</CODE>, <CODECLASS="literal">printf</CODE>, and <CODECLASS="literal">write</CODE> functions. Change this with <CODECLASS="literal">select</CODE><ACLASS="indexterm"NAME="ch07-idx-1000009576-0"></A>, which takes the new default output filehandle and returns the previous one. The new output filehandle should have been opened before calling <CODECLASS="literal">select</CODE>:</P><PRECLASS="programlisting">$old_fh = select(LOGFILE); # switch to LOGFILE for outputprint "Countdown initiated ...\n";select($old_fh); # return to original outputprint "You have 30 seconds to reach minimum safety distance.\n";</PRE><PCLASS="para">Some of Perl's special variables change the behavior of the currently selected output filehandle. Most important is <CODECLASS="literal">$|</CODE><ACLASS="indexterm"NAME="ch07-idx-1000009577-0"></A>, which controls output buffering for each filehandle. Buffering is explained in <ACLASS="xref"HREF="ch07_13.htm"TITLE="Flushing Output">Recipe 7.12</A>.</P><PCLASS="para"><ACLASS="indexterm"NAME="ch07-idx-1000009578-0"></A><ACLASS="indexterm"NAME="ch07-idx-1000009578-1"></A><ACLASS="indexterm"NAME="ch07-idx-1000009578-2"></A>Perl provides functions for buffered and unbuffered input and output. Although there are some exceptions, you shouldn't mix calls to buffered and unbuffered I/O functions. The following table shows the two sets of functions you should not mix. Functions on a particular row are only loosely associated; for instance, <CODECLASS="literal">sysread</CODE> doesn't have the same semantics as <CODECLASS="literal">< ></CODE>, but they are on the same row because they both read input from a filehandle.</P><TABLECLASS="informaltable"BORDER="1"CELLPADDING="3"><THEADCLASS="thead"><TRCLASS="row"VALIGN="TOP"><THCLASS="entry"ALIGN="LEFT"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><BCLASS="emphasis.bold">Action</B></P></TH><THCLASS="entry"ALIGN="LEFT"ROWSPAN="1"COLSPAN="1"><PCLASS="para">Buffered</P></TH><THCLASS="entry"ALIGN="LEFT"ROWSPAN="1"COLSPAN="1"><PCLASS="para">Unbuffered</P></TH></TR></THEAD><TBODYCLASS="tbody"><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para">opening</P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">open,sysopen</CODE></P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">sysopen </CODE></P></TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para">closing</P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">close</CODE></P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">close </CODE></P></TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para">input</P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal"><FILE>,readline</CODE></P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">sysread </CODE></P></TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para">output</P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">print</CODE></P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">syswrite </CODE></P></TD></TR><TRCLASS="row"VALIGN="TOP"><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para">repositioning</P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">seek, tell</CODE></P></TD><TDCLASS="entry"ROWSPAN="1"COLSPAN="1"><PCLASS="para"><CODECLASS="literal">sysseek </CODE></P></TD></TR></TBODY></TABLE><PCLASS="para">Repositioning is addressed in <ACLASS="xref"HREF="ch08_01.htm"TITLE="File Contents">Chapter 8</A>, but we also use it in <ACLASS="xref"HREF="ch07_11.htm"TITLE="Modifying a File in Place Without a Temporary File">Recipe 7.10</A>.<ACLASS="indexterm"NAME="ch07-idx-1000009568-0"></A></P></DIV></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch06_24.htm"TITLE="6.23. Regular Expression Grabbag"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 6.23. Regular Expression Grabbag"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch07_02.htm"TITLE="7.1. Opening a File"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 7.1. Opening a File"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">6.23. Regular Expression Grabbag</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">7.1. Opening a File</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -