⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch11_02.htm

📁 by Randal L. Schwartz and Tom Phoenix ISBN 0-596-00132-0 Third Edition, published July 2001. (See
💻 HTM
字号:
<html><head><title>Opening a Filehandle (Learning Perl, 3rd Edition)</title><link rel="stylesheet" type="text/css" href="../style/style1.css" /><meta name="DC.Creator" content="Randal L. Schwartz and Tom Phoenix" /><meta name="DC.Format" content="text/xml" scheme="MIME" /><meta name="DC.Language" content="en-US" /><meta name="DC.Publisher" content="O'Reilly &amp; Associates, Inc." /><meta name="DC.Source" scheme="ISBN" content="0596001320L" /><meta name="DC.Subject.Keyword" content="stuff" /><meta name="DC.Title" content="Learning Perl, 3rd Edition" /><meta name="DC.Type" content="Text.Monograph" /></head><body bgcolor="#ffffff"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Learning Perl, 3rd Edition" /><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch11_01.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"></a></td><td align="right" valign="top" width="228"><a href="ch11_03.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr></table></div><h2 class="sect1">11.2. Opening a Filehandle</h2><p><a name="INDEX-746" /><a name="INDEX-747" />So we see that Perl provides threefilehandles -- <tt class="literal">STDIN</tt>,<tt class="literal">STDOUT</tt>, and <tt class="literal">STDERR</tt> -- whichare automatically open to files or devices established by theprogram's parent process (probably the shell). When you needother filehandles, use the <tt class="literal">open</tt> operator to tellPerl to ask the operating system to open the connection between yourprogram and the outside world. Here are some examples:</p><blockquote><pre class="code">open CONFIG, "dino";open CONFIG, "&lt;dino";open BEDROCK, "&gt;fred";open LOG, "&gt;&gt;logfile";</pre></blockquote><p>The first one opens a filehandle called <tt class="literal">CONFIG</tt> toa file called <em class="filename">dino</em>. That is, the (existing) file<em class="filename">dino</em> will be opened and whatever it holds willcome into our program through the filehandle named<tt class="literal">CONFIG</tt>. This is similar to the way that data froma file could come in through <tt class="literal">STDIN</tt> if the commandline had a shell redirection like <tt class="literal">&lt;dino</tt>. Infact, the second example uses exactly that sequence. The second doesthe same as the first, but the less-than sign explicitly says"this filename is to be used for input," even thoughthat's the default.<a href="#FOOTNOTE-248">[248]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-248" /><p>[248]This may be important forsecurity reasons. As we'll see in a moment (and in furtherdetail in <a href="ch14_01.htm">Chapter 14, "Process Management"</a>), there are a number ofmagical characters that may be used in filenames. If<tt class="literal">$name</tt> holds a user-chosen filename, simply opening<tt class="literal">$name</tt> will allow any of these magical charactersto come into play. This could be a convenience tn the user, or itcould be a security hole. But opening <tt class="literal">"&lt;$name"</tt>is much safer, since it explicitly says to open the given name forinput. Still, this doesn't prevent all possible mischief. Formore information on different ways of opening files, especially whensecurity may be a concern, see the <em class="emphasis">perlopentut</em>manpage.</p> </blockquote><p>Although you don't have to use the <a name="INDEX-748" /> <a name="INDEX-749" />less-than sign toopen a file for input, we include that because, as you can see in thethird example, a <a name="INDEX-750" /> <a name="INDEX-751" />greater-than signmeans to create a new file for output. This opens the filehandle<tt class="literal">BEDROCK</tt> for output to the new file<em class="filename">fred</em>. Just as when the greater-then sign is usedin shell redirection, we're sending the output to a<em class="emphasis">new</em> file called <em class="filename">fred</em>. Ifthere's already a file of that name, we're asking to wipeit out and replace it with this new one.</p><p>The fourth example shows how two greater-than signs may be used(again, as the shell does) to open a file for appending. That is, ifthe file already exists, we will add new data at the end. If itdoesn't exist, it will be created in much the same way as if wehad used just one greater-than sign. This is handy for<a name="INDEX-752" />log files; your program could write a fewlines to the end of a log file each time it's run. Sothat's why the fourth example names the filehandle<tt class="literal">LOG</tt> and the file <em class="filename">logfile</em>.</p><p>You can use any scalar expression in place of the filename specifier,although typically you'll want to be explicit about thedirection specification:</p><blockquote><pre class="code">my $selected_output = "my_output";open LOG, "&gt; $selected_output";</pre></blockquote><p>Note the<a name="INDEX-753" />space after the greater-than. Perl ignoresthis,<a href="#FOOTNOTE-249">[249]</a> but it keepsunexpected things from happening if<tt class="literal">$selected_output</tt> were<tt class="literal">"&gt;passwd"</tt> for example (which would make anappend instead of a write).</p><blockquote class="footnote"> <a name="FOOTNOTE-249" /><p>[249]Yes, this means that if your filename were tohave leading whitespace, that would also be ignored by Perl. See<em class="emphasis">perlfunc</em> and <em class="emphasis">perlopentut</em> ifyou're worried about this.</p> </blockquote><p>We'll see how to use these filehandles later in this chapter.</p><a name="lperl3-CHP-11-SECT-2.1" /><div class="sect2"><h3 class="sect2">11.2.1. Closing a Filehandle</h3><p>When you are finished with a filehandle, you may close it with the<tt class="literal">close</tt><a name="INDEX-754" /> operator like this:</p><blockquote><pre class="code">close BEDROCK;</pre></blockquote><p>Closing a filehandle tells Perl to inform the operating system thatwe're all done with the given data stream, so any last outputdata should be written to disk in case someone is waiting forit.<a href="#FOOTNOTE-250">[250]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-250" /><p>[250]If you know much about I/O systems, you'llknow there's more to the story. Generally, though, when afilehandle is closed, here's what happens. If there'sinput remaining in a file, it's ignored. If there's inputremaining in a pipeline, the writing program may get a signal thatthe pipeline is closed. If there's output going to a file orpipeline, the buffer is flushed (that is, pending output is sent onits way). If the filehandle had a lock, the lock is released. Seeyour system's I/O documentation for further details.</p></blockquote><p>Perl will automatically close a filehandle if you reopen it (that is,if you reuse the filehandle name in a new <tt class="literal">open</tt>)or if you exit the program.<a href="#FOOTNOTE-251">[251]</a> Because of this, manysimple Perl programs don't bother with<tt class="literal">close</tt>. But it's there if you want to betidy, with one <tt class="literal">close</tt> for every<tt class="literal">open</tt>. In general, it's best to close eachfilehandle soon after you're done with it, though the end ofthe program often arrives soon enough.<a href="#FOOTNOTE-252">[252]</a></p><blockquote class="footnote"> <a name="FOOTNOTE-251" /><p>[251]Any exit from the programwill close all filehandles, but if Perl itself breaks, pending outputbuffers won't get flushed. That is to say, if you accidentallycrash your program by dividing by zero, for example, Perl itself isstill running. Perl will ensure that data you've writtenactually gets output in that case. But if Perl itself can't run(because you ran out of memory or caught an unexpected signal), thelast few pieces of output may not be written to disk. Usually, thisisn't a big issue.</p> </blockquote><blockquote class="footnote"> <a name="FOOTNOTE-252" /><p>[252]Closing afilehandle will flush any output buffers and release any locks on thefile. Since someone else may be waiting for those things, along-running program should generally close each filehandle as soonas possible. But many of our programs will take only one or twoseconds to run to completion, so this may not matter. Closing afilehandle also releases possibly limited resources, so it'smore than just being tidy.</p> </blockquote></div><a name="lperl3-CHP-11-SECT-2.2" /><div class="sect2"><h3 class="sect2">11.2.2. Bad Filehandles</h3><p>Perl can't actually open a file all by itself. Like any otherprogramming language, Perl can merely ask the operating system to letus open a file. Of course, the operating system may refuse, becauseof permission settings, an incorrect filename, or other reasons.</p><p>If you try to read from a bad filehandle (that is, a filehandle thatisn't properly open), you'll see an immediate<a name="INDEX-755" /><a name="INDEX-756" /><a name="INDEX-757" />end-of-file. (With the I/Omethods we'll see in this chapter, end-of-file will beindicated by <tt class="literal">undef</tt> in a scalar context or an emptylist in a list context.) If you try to write to a bad filehandle, thedata is silently discarded.</p><p>Fortunately, these dire consequences are easy to avoid. First of all,if we ask for <a name="INDEX-758" />warnings with<tt class="literal">-w</tt>, Perl will generally be able to tell us with awarning when it sees that we're using a bad filehandle. Buteven before that, <tt class="literal">open</tt> always tells us if itsucceeded or failed, by returning true for success or false forfailure. So you could write code like this:</p><blockquote><pre class="code">my $success = open LOG, "&gt;&gt;logfile";  # capture the return valueunless ($success) {  # The open failed  ...}</pre></blockquote><p>Well, you <em class="emphasis">could</em> do it like that, butthere's another way that we'll see in the nextsection.<a name="INDEX-759" /><a name="INDEX-760" /></p></div><hr width="684" align="left" /><div class="navbar"><table width="684" border="0"><tr><td align="left" valign="top" width="228"><a href="ch11_01.htm"><img alt="Previous" border="0" src="../gifs/txtpreva.gif" /></a></td><td align="center" valign="top" width="228"><a href="index.htm"><img alt="Home" border="0" src="../gifs/txthome.gif" /></a></td><td align="right" valign="top" width="228"><a href="ch11_03.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">11. Filehandles and File Tests</td><td align="center" valign="top" width="228"><a href="index/index.htm"><img alt="Book Index" border="0" src="../gifs/index.gif" /></a></td><td align="right" valign="top" width="228">11.3. Fatal Errors with die</td></tr></table></div><hr width="684" align="left" /><img alt="Library Navigation Links" border="0" src="../gifs/navbar.gif" usemap="#library-map" /><p><p><font size="-1"><a href="copyrght.htm">Copyright &copy; 2002</a> O'Reilly &amp; 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 + -