ch11_06.htm

来自「by Randal L. Schwartz and Tom Phoenix I」· HTM 代码 · 共 924 行 · 第 1/3 页

HTM
924
字号
<a name="INDEX-826" />timestamps, buthere they're represented in the system's timestampformat: a 32-bit number telling how many seconds have passed sincethe <em class="firstterm">Epoch</em>, an arbitrary starting point formeasuring <a name="INDEX-827" />systemtime. On Unix systems and some others, the<a name="INDEX-828" />Epoch is the beginningof 1970 at midnight Universal Time, but the Epoch is different onsome machines. There's more information later in this chapteron turning that timestamp number into something useful.</p></dd></dl><p>Invoking <tt class="literal">stat</tt> on the name of a<a name="INDEX-829" />symbolic linkreturns information on what the symbolic link points at, notinformation about the symbolic link itself (unless the link justhappens to be pointing at nothing currently accessible). If you needthe (mostly useless) information about the symbolic link itself, use<tt class="literal">lstat</tt><a name="INDEX-830" /> rather than <tt class="literal">stat</tt>(which returns the same information in the same order). If theoperand isn't a symbolic link, <tt class="literal">lstat</tt>returns the same things that <tt class="literal">stat</tt> would.</p><p>Like the file tests, the operand of <tt class="literal">stat</tt> or<tt class="literal">lstat</tt> defaults to <tt class="literal">$_</tt>,meaning that the underlying stat system call will be performed on thefile named by the scalar variable <tt class="literal">$_</tt>.</p></div><a name="lperl3-CHP-11-SECT-6.2" /><div class="sect2"><h3 class="sect2">11.6.2. The localtime Function</h3><p>When you have a <a name="INDEX-831" /><a name="INDEX-832" />timestamp number (such as the onesfrom <tt class="literal">stat</tt>), it will typically look something like1080630098. That's not very useful for most humans, unless youneed to compare two timestamps by subtracting. You may need toconvert it to something human-readable, such as a string like"<tt class="literal">Tue Mar 30 07:01:38 2004</tt>". Perl cando that with the <tt class="literal">localtime</tt> function in a scalarcontext:</p><blockquote><pre class="code">my $timestamp = 1080630098;my $date = localtime $timestamp;</pre></blockquote><p>In a list context, <tt class="literal">localtime</tt> returns a list ofnumbers, several of which may not be quite what you'd expect:</p><blockquote><pre class="code">my($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst)  = localtime $timestamp;</pre></blockquote><p>The <tt class="literal">$mon</tt> is a month number, ranging from<tt class="literal">0</tt> to <tt class="literal">11</tt>, which is handy as anindex into an array of month names. The <tt class="literal">$year</tt> isthe number of years since 1900, oddly enough, so add<tt class="literal">1900</tt> to get the real year number. The<tt class="literal">$wday</tt> ranges from <tt class="literal">0</tt> (forSunday) through <tt class="literal">6</tt> (for Saturday), and the<tt class="literal">$yday</tt> is the day-of-the-year (ranging from 0 forJanuary 1, through 364 or 365 for December 31).</p><p>There are two related functions that you'll also find useful.The <tt class="literal">gmtime</tt><a name="INDEX-833" /> function is just the same as<tt class="literal">localtime</tt>, except that it returns the time in<a name="INDEX-834" />UniversalTime (what we once called <a name="INDEX-835" />Greenwich Mean Time). If you need thecurrent timestamp number from the system clock, just use the<tt class="literal">time</tt><a name="INDEX-836" /> function. Both<tt class="literal">localtime</tt> and <tt class="literal">gmtime</tt> default tousing the current <tt class="literal">time</tt> value if you don'tsupply a parameter:</p><blockquote><pre class="code">my $now = gmtime;  # Get the current universal timestamp as a string</pre></blockquote><p>For more information on manipulating date and time information, seethe information about some useful modules in <a href="appb_01.htm">Appendix B, "Beyond the Llama"</a>.</p></div><a name="lperl3-CHP-11-SECT-6.3" /><div class="sect2"><h3 class="sect2">11.6.3. Bitwise Operators</h3><p><a name="INDEX-837" />When you need to work with numbersbit-by-bit, as when working with the mode bits returned by<tt class="literal">stat</tt>, you'll need to use the bitwiseoperators. The bitwise-and operator (<tt class="literal">&amp;</tt>)reports which bits are set in the left argument<em class="emphasis">and</em> in the right argument. For example, theexpression <tt class="literal">10 &amp; 12</tt> has the value<tt class="literal">8</tt>. The bitwise-and needs to have a one-bit in bothoperands to produce a one-bit in the result. That means that thelogical-and operation on ten (which is <tt class="literal">1010</tt> inbinary) and twelve (which is <tt class="literal">1100</tt>) gives eight(which is <tt class="literal">1000</tt>, with a one-bit only where the leftoperand has a one-bit <em class="emphasis">and</em> the right operand alsohas a one-bit). See <a href="ch11_06.htm#lperl3-CHP-11-FIG-1">Figure 11-1</a>.</p><a name="lperl3-CHP-11-FIG-1" /><div class="figure"><img height="88" alt="Figure 11-1" src="figs/lrnp_1101.gif" width="99" /></div><h4 class="objtitle">Figure 11-1. Bitwise-and addition</h4><p>The different bitwise operators and their meanings are shown in thistable:</p><a name="ch11-9-fm2xml" /><table border="1"><tr><th><p>Expression</p></th><th><p>Meaning</p></th></tr><tr><td><blockquote><pre class="code">10 &amp; 12</pre></blockquote></td><td><p>Bitwise-and -- which bits are true in both operands (this gives<tt class="literal">8</tt>)</p></td></tr><tr><td><blockquote><pre class="code">10 | 12</pre></blockquote></td><td><p>Bitwise-or -- which bits are true in one operand or the other(this gives <tt class="literal">14</tt>)</p></td></tr><tr><td><blockquote><pre class="code">10 ^ 12</pre></blockquote></td><td><p>Bitwise-xor -- which bits are true in one operand or the other butnot both (this gives <tt class="literal">6</tt>)</p></td></tr><tr><td><blockquote><pre class="code">6 &lt;&lt; 2</pre></blockquote></td><td><p>Bitwise shift left -- shift the left operand the number of bitsshown by the right operand, adding zero-bits at the least-significantplaces (this gives <tt class="literal">24</tt>)</p></td></tr><tr><td><blockquote><pre class="code">25 &gt;&gt; 2</pre></blockquote></td><td><p>Bitwise shift right -- shift the left operand the number of bitsshown by the right operand, discarding the least-significant bits(this gives <tt class="literal">6</tt>)</p></td></tr><tr><td><blockquote><pre class="code">~ 10</pre></blockquote></td><td><p>Bitwise negation, also called unary bit complement -- return thenumber with the opposite bit for each bit in the operand (this gives<tt class="literal">0xFFFFFFF5</tt>, but see the text)</p></td></tr></table><p><p>So, here's an example of some things you could do with the<tt class="literal">$mode</tt> returned by <tt class="literal">stat</tt>. Theresults of these bit manipulations could be useful with<tt class="literal">chmod</tt>, which we'll see in <a href="ch13_01.htm">Chapter 13, "Manipulating Files and Directories"</a>: </p><blockquote><pre class="code"># $mode is the mode value returned from a stat of CONFIGwarn "Hey, the configuration file is world-writable!\n"  if $mode &amp; 0002;                                # configuration security problemmy $classical_mode = 0777 &amp; $mode;                # mask off extra high-bitsmy $u_plus_x = $classical_mode | 0100;            # turn one bit onmy $go_minus_r = $classical_mode &amp; (~ 0044);      # turn two bits off</pre></blockquote></div><a name="lperl3-CHP-11-SECT-6.4" /><div class="sect2"><h3 class="sect2">11.6.4. Using Bitstrings</h3><p>All of the bitwise operators can work with<a name="INDEX-838" />bitstrings, aswell as with integers. If the operands are integers, the result willbe an integer. (The integer will be at least a 32-bit integer, butmay be larger if your machine supports that. That is, if you have a64-bit machine, <tt class="literal">~10</tt> may give the 64-bit result<tt class="literal">0xFFFFFFFFFFFFFFF5</tt>, rather than the 32-bit result<tt class="literal">0xFFFFFFF5</tt>.) </p><p>But if any operand of a bitwise operator is a string, Perl willperform the operation on that bitstring. That is, <tt class="literal">"\xAA" |"\x55"</tt> will give the string <tt class="literal">"\xFF"</tt>. Notethat these values are single-byte strings; the result is a byte withall eight bits set. Bitstrings may be arbitrarily long.</p><p>This is one of the very few places where Perl distinguishes betweenstrings and numbers. See the<em class="emphasis">perlop</em><a name="INDEX-839" /> <a name="INDEX-840" />manpage for more information on using bitwise operators onstrings.<a name="INDEX-841" /></p></div><a name="lperl3-CHP-11-SECT-6.5" /><div class="sect2"><h3 class="sect2">11.6.5. Using the Special Underscore Filehandle</h3><p>Every time you use <tt class="literal">stat</tt>,<tt class="literal">lstat</tt>, or a file test in a program, Perl has to goout to the system to ask for a <a name="INDEX-842" /><a name="INDEX-843" />statbuffer on the file (that is, the return buffer from the stat systemcall). That means if you want to know whether a file is both readableand writable, you've essentially asked the system twice for thesame information (which isn't likely to change in a fairlynonhostile environment).</p><p>This looks like a waste of time,<a href="#FOOTNOTE-274">[274]</a> and in fact, it can be avoided. Doing a file test,<tt class="literal">stat</tt><a name="INDEX-844" />, or<tt class="literal">lstat</tt><a name="INDEX-845" /> on the special<tt class="literal">_</tt><a name="INDEX-846" /> <a name="INDEX-847" /><a name="INDEX-848" />filehandle (that is, the operand is nothing but a single underscore)tells Perl to use whatever happened to be lounging around in memoryfrom the previous file test, <tt class="literal">stat</tt>, or<tt class="literal">lstat</tt> function, rather than going out to theoperating system again. Sometimes this is dangerous: a subroutinecall can invoke <tt class="literal">stat</tt> without your knowledge,blowing your buffer away. But if you're careful, you can saveyourself a few unneeded system calls, thereby making your programconsiderably faster. Here's that example of finding files toput on the backup tapes again, using the new tricks we'velearned:</p><blockquote class="footnote"> <a name="FOOTNOTE-274" /><p>[274]Because it is.Asking the system for information is relatively slow.</p></blockquote><blockquote><pre class="code">my @original_files = qw/ fred barney betty wilma pebbles dino bamm-bamm /;my @big_old_files;                       # The ones we want to put on backup tapesforeach (@original_files) {  push @big_old_files, $_    if (-s) &gt; 100_000 and -A _ &gt; 90;     # More efficient than before}</pre></blockquote><p>Note that we used the default of <tt class="literal">$_</tt> for the firsttest -- this is no more efficient (except perhaps for theprogrammer), but it gets the data from the operating system. Thesecond test uses the magic <tt class="literal">_</tt> filehandle; for thistest, the data left around after getting the file's size isused, which is exactly what we want.</p><p>Note that testing the <tt class="literal">_</tt> filehandle is not the sameas allowing the operand of a file test, <tt class="literal">stat</tt>, or<tt class="literal">lstat</tt> to default to testing<tt class="literal">$_</tt>; using <tt class="literal">$_</tt> would be a freshtest each time on the current file named by the contents of<tt class="literal">$_</tt>, but using <tt class="literal">_</tt> saves thetrouble of calling the system again. Here is another case wheresimilar names were chosen for radically different functions. By now,you are probably used to<a name="INDEX-849" /> it.<a name="INDEX-850" /></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_05.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_07.htm"><img alt="Next" border="0" src="../gifs/txtnexta.gif" /></a></td></tr><tr><td align="left" valign="top" width="228">11.5. Reopening a Standard Filehandle</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.7. Exercises</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 + =
减小字号Ctrl + -
显示快捷键?