📄 ch07_21.htm
字号:
<HTML><HEAD><TITLE>Recipe 7.20. Copying Filehandles (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:37:36Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch07_01.htm"TITLE="7. File Access"><LINKREL="prev"HREF="ch07_20.htm"TITLE="7.19. Opening and Closing File Descriptors by Number"><LINKREL="next"HREF="ch07_22.htm"TITLE="7.21. Program: netlock"></HEAD><BODYBGCOLOR="#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="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch07_20.htm"TITLE="7.19. Opening and Closing File Descriptors by Number"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 7.19. Opening and Closing File Descriptors by Number"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch07_01.htm"TITLE="7. File Access"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch07_22.htm"TITLE="7.21. Program: netlock"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 7.21. Program: netlock"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch07-chap07_copying_0">7.20. Copying Filehandles</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch07-pgfId-1928">Problem<ACLASS="indexterm"NAME="ch07-idx-1000009796-0"></A><ACLASS="indexterm"NAME="ch07-idx-1000009796-1"></A><ACLASS="indexterm"NAME="ch07-idx-1000009796-2"></A><ACLASS="indexterm"NAME="ch07-idx-1000009796-3"></A></A></H3><PCLASS="para">You want to make a copy of a filehandle.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch07-pgfId-1934">Solution</A></H3><PCLASS="para">To create an alias for a filehandle, say:</P><PRECLASS="programlisting">*ALIAS = *ORIGINAL;</PRE><PCLASS="para">Use <CODECLASS="literal">open</CODE> with the <CODECLASS="literal">&</CODE> mode to create an independent copy of the file descriptor for the filehandle:</P><PRECLASS="programlisting">open(OUTCOPY, ">&STDOUT") or die "Couldn't dup STDOUT: $!";open(INCOPY, "<&STDIN" ) or die "Couldn't dup STDIN : $!";</PRE><PCLASS="para">Use <CODECLASS="literal">open</CODE> with the <CODECLASS="literal">&=</CODE> mode to create an alias for that filehandle's file descriptor:</P><PRECLASS="programlisting">open(OUTALIAS, ">&=STDOUT") or die "Couldn't alias STDOUT: $!";open(INALIAS, "<&=STDIN") or die "Couldn't alias STDIN : $!";open(BYNUMBER, ">&=5") or die "Couldn't alias file descriptor 5: $!";</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch07-pgfId-1956">Discussion</A></H3><PCLASS="para">If you create an alias for a filehandle with <ACLASS="indexterm"NAME="ch07-idx-1000012077-0"></A>typeglobs, only one Perl I/O object is still being accessed. If you close one of these aliased filehandles, the I/O object is closed. Any subsequent attempt to use a copy of that filehandle will give you an error like <CODECLASS="literal">"print</CODE> <CODECLASS="literal">on</CODE> <CODECLASS="literal">closed</CODE> <CODECLASS="literal">filehandle"</CODE>. When alternating access through the aliased filehandles, writes work as you'd expect because there's no duplicated stdio data structure to get out of sync.</P><PCLASS="para">If you create a copy of a file descriptor with <CODECLASS="literal">open(COPY,</CODE> <CODECLASS="literal">">&HANDLE")</CODE>, you're really calling the <ICLASS="filename">dup</I><EMCLASS="emphasis"> </EM>(2) system call. You get two independent file descriptors whose file position, locks, and flags are shared, but which have independent stdio buffers. Closing one filehandle doesn't affect its copy. Simultaneously accessing the file through both filehandles is a recipe for disaster. Instead, this technique is normally used to save and restore STDOUT and STDERR:</P><PRECLASS="programlisting"># take copies of the file descriptorsopen(OLDOUT, ">&STDOUT");open(OLDERR, ">&STDERR");# redirect stdout and stderropen(STDOUT, "> /tmp/program.out") or die "Can't redirect stdout: $!";open(STDERR, ">&STDOUT") or die "Can't dup stdout: $!";# run the programsystem($joe_random_program);# close the redirected filehandlesclose(STDOUT) or die "Can't close STDOUT: $!";close(STDERR) or die "Can't close STDERR: $!";# restore stdout and stderropen(STDERR, ">&OLDERR") or die "Can't restore stderr: $!";open(STDOUT, ">&OLDOUT") or die "Can't restore stdout: $!";# avoid leaks by closing the independent copiesclose(OLDOUT) or die "Can't close OLDOUT: $!";close(OLDERR) or die "Can't close OLDERR: $!";</PRE><PCLASS="para">If you create an alias of a file descriptor using <CODECLASS="literal">open(ALIAS,</CODE> <CODECLASS="literal">">&=HANDLE"</CODE>), you're really calling the <ICLASS="filename">fdopen</I><EMCLASS="emphasis"> </EM>(3) stdio function. You get a single file descriptor with two stdio buffers accessed through two filehandles. Closing one filehandle closes the file descriptor of any aliases, but not their filehandles - if you tried to <CODECLASS="literal">print</CODE> to a filehandle whose alias had been <CODECLASS="literal">close</CODE>d, Perl wouldn't give a <CODECLASS="literal">"print on closed filehandle warning"</CODE> even though the <CODECLASS="literal">print</CODE> didn't succeed. In short, accessing the file through both filehandles is also a recipe for disaster. This is really used only to open a file descriptor by number. See <ACLASS="xref"HREF="ch07_20.htm"TITLE="Opening and Closing File Descriptors by Number">Recipe 7.19</A> for more information on this.<ACLASS="indexterm"NAME="ch07-idx-1000009798-0"></A><ACLASS="indexterm"NAME="ch07-idx-1000009798-1"></A><ACLASS="indexterm"NAME="ch07-idx-1000009798-2"></A><ACLASS="indexterm"NAME="ch07-idx-1000009798-3"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch07-pgfId-2010">See Also</A></H3><PCLASS="para">The <CODECLASS="literal">open</CODE> function in <ICLASS="filename">perlfunc </I>(1) and in <ACLASS="olink"HREF="../prog/ch03_01.htm">Chapter 3</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; your system's <ICLASS="filename">dup</I> (2) manpage</P></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="ch07_20.htm"TITLE="7.19. Opening and Closing File Descriptors by Number"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 7.19. Opening and Closing File Descriptors by Number"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_22.htm"TITLE="7.21. Program: netlock"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 7.21. Program: netlock"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">7.19. Opening and Closing File Descriptors by Number</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.21. Program: netlock</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 + -