📄 ch9.htm
字号:
</BLOCKQUOTE><P>With binary mode on, bytes with a value of 26 have no specialmeaning and the third line can be read. You see that the value26-33 in hexadecimal-was printed along with the rest of the characters.<P><TT>Example: Reading into a Hash</TT><P>You've already seen that you can read a file directly into a regulararray using this syntax:<BLOCKQUOTE><PRE>@array = <FILE_HANDLE>;</PRE></BLOCKQUOTE><P>Unfortunately, there is no similar way to read an entire fileinto a hash. But, it's still pretty easy to do. The followingexample will use the line number as the hash key for each lineof a file.<P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Open the </I><TT><I>FIXED.DAT</I></TT><I>file for reading.<BR>For each line of </I><TT><I>FIXED.DAT </I></TT><I>createa hash element using the record number special variable (</I><TT><I>$.</I></TT><I>)as the key and the line of input (</I><TT><I>$_</I></TT><I>)as the value.<BR>Close the file.<BR>Iterate over the keys of the hash.<BR>Print each key, value pair.</I></BLOCKQUOTE><HR><BLOCKQUOTE><B>Listing 9.12 09LST12.PL-Reading a Fixed Length Recordwith Fixed Length Fields into a Hash<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>open(FILE, "<fixed.dat");while (<FILE>) { $hash{$.} = $_;}close(FILE);foreach (keys %hash) { print("$_: $hash{$_}");}</PRE></BLOCKQUOTE><HR><P>This program displays:<BR><BLOCKQUOTE><PRE>1: 1212Jan Jaspree Painter2: 3453Kelly Horton Jockey</PRE></BLOCKQUOTE><H3><A NAME="ExampleGettingFileStatistics">Example: Getting File Statistics</A></H3><P>The file test operators can tell you a lot about a file, but sometimesyou need more. In those cases, you use the <TT>stat()</TT>or <TT>lstat()</TT> fuNCtion. The<TT>stat()</TT> returns file informationin a 13-element array. You can pass either a file handle or afile name as the parameter. If the file can't be found or anothererror occurs, the null list is returned. Listing 9.13 shows howto use the <TT>stat()</TT> fuNCtionto find out information about the <TT>EOF.DAT</TT>file used earlier in the chapter.<P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Assign the return list from the </I><TT><I>stat()</I></TT><I>fuNCtion to 13 scalar variables.<BR>Print the scalar values.</I></BLOCKQUOTE><HR><BLOCKQUOTE><B>Listing 9.13 09LST13.PL-Using the </B><TT><I><B><FONT FACE="Courier">stat()</FONT></B></I></TT><B>FuNCtion<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat("eof.dat");print("dev = $dev\n");print("ino = $ino\n");print("mode = $mode\n");print("nlink = $nlink\n");print("uid = $uid\n");print("gid = $gid\n");print("rdev = $rdev\n");print("size = $size\n");print("atime = $atime\n");print("mtime = $mtime\n");print("ctime = $ctime\n");print("blksize = $blksize\n");print("blocks = $blocks\n");</PRE></BLOCKQUOTE><HR><P>In the DOS environment, this program displays:<BLOCKQUOTE><PRE>dev = 2ino = 0mode = 33206nlink = 1uid = 0gid = 0rdev = 2size = 13atime = 833137200mtime = 833195316ctime = 833194411blksize =blocks =</PRE></BLOCKQUOTE><P>Some of this information is specific to the UNIX environment andis beyond the scope of this book. For more information on thistopic, see Que's 1994 edition of <I>Using Unix</I>. One interestingpiece of information is the <TT>$mtime</TT>value-the date and time of the last modification made to the file.You can interpret this value by using the following line of code:<BLOCKQUOTE><PRE>($sec, $min, $hr, $day, $month, $year, $day_Of_Week, $julianDate, $dst) = localtime($mtime);</PRE></BLOCKQUOTE><P>If you are only interested in the modification date, you can usethe array slice notation to just grab that value from the 13-elementarray returned by <TT>stat()</TT>.For example:<BLOCKQUOTE><PRE>$mtime = (stat("eof.dat"))[9];</PRE></BLOCKQUOTE><P>Notice that the <TT>stat()</TT> fuNCtionis surrounded by parentheses so that the return value is evaluatedin an array context. Then the tenth element is assigned to <TT>$mtime</TT>.You can use this technique whenever a fuNCtion returns a list.<H3><A NAME="ExampleUsingtheDirectoryFuNCtions">Example: Using the Directory FuNCtions</A></H3><P>Perl has several fuNCtions that let you work with directories.You can make a directory with the <TT>mkdir()</TT>fuNCtion. You can delete a directory with the <TT>rmdir()</TT>fuNCtion. Switching from the current directory to another is doneusing the <TT>chdir()</TT> fuNCtion.<P>Finding out which files are in a directory is done with the <TT>opendir()</TT>,<TT>readdir()</TT>, and <TT>closedir()</TT>fuNCtions. The next example will show you how to create a listof all Perl programs in the current directory-well, at least thosefiles that end with the pl extension.<P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Open the current directory using </I><TT><I>DIR</I></TT><I>as the directory handle.<BR>Read a list of file names using the </I><TT><I>readdir()</I></TT><I>fuNCtion; extract only those that end in </I><TT><I>pl</I></TT><I>;and the sorted list. The sorted list is assigned to the </I><TT><I>@files</I></TT><I>array variable.<BR>Close the directory.<BR>Print the file names from the </I><TT><I>@files</I></TT><I>array unless the file is a directory.</I></BLOCKQUOTE><HR><BLOCKQUOTE><B>Listing 9.14 09LST14.PL-Print All Files in the CurrentDirectory Whose Name Ends in PL<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>opendir(DIR, ".");@files = sort(grep(/pl$/, readdir(DIR)));closedir(DIR);foreach (@files) { print("$_\n") unless -d;}</PRE></BLOCKQUOTE><HR><P>For more information about the grep() fuNCtion, see <A HREF="ch10.htm" >Chapter 10</A>,"Regular Expressions." <P>This program will display each file name that ends in <TT>pl</TT>on a separate line. If you need to know the number of Perl programs,evaluate the <TT>@files</TT> arrayin a scalar context. For example:<BLOCKQUOTE><PRE>$num_Perl_Programs = @files;<BR></PRE></BLOCKQUOTE><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Tip</B></TD></TR><TR><TD><BLOCKQUOTE>For this example, I modified the naming convention used for the variables. I feel that <TT>$num_Perl_Programs</TT> is easier to read than <TT>$numPerlPrograms</TT>. No naming convention should be inflexible. Use it as a guideline and break the rules when it seems wise.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><H3><A NAME="ExamplePrintingRevisited">Example: Printing Revisited</A></H3><P>We've been using the <TT>print()</TT>fuNCtion throughout this book without really looking at how itworks. Let's remedy that now.<P>The <TT>print()</TT> fuNCtion is usedto send output to a file handle. Most of the time, we've beenusing <TT>STDOUT</TT> as the filehandle. Because <TT>STDOUT</TT> isthe default, we did not need to specify it. The syntax for the<TT>print()</TT> fuNCtion is:<BLOCKQUOTE><PRE>print FILE_HANDLE (LIST)</PRE></BLOCKQUOTE><P>You can see from the syntax that <TT>print()</TT>is a list operator because it's looking for a list of values toprint. If you don't specify a list, then $ will be used. Youcan change the default file handle by using the <TT>select()</TT>fuNCtion. Let's take a look at this:<P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Open </I><TT><I>TESTFILE.DAT</I></TT><I>for output.<BR>Change the default file handle for write and print statements.Notice that the old default handle is returned and saved in the</I><TT><I>$oldHandle</I></TT><I>variable.<BR>This line prints to the default handle which now the </I><TT><I>TESTFILE.DAT</I></TT><I>file.<BR>Change the default file handle back to </I><TT><I>STDOUT</I></TT><I>.<BR>This line prints to </I><TT><I>STDOUT</I></TT><I>.</I></BLOCKQUOTE><BLOCKQUOTE><PRE>open(OUTPUT_FILE, ">testfile.dat");$oldHandle = select(OUTPUT_FILE);print("This is line 1.\n");select($oldHandle);print("This is line 2.\n");</PRE></BLOCKQUOTE><P>This program displays:<BLOCKQUOTE><PRE>This is line 2.</PRE></BLOCKQUOTE><P>and creates the TESTFILE.DAT file with a single line in it:<BLOCKQUOTE><PRE>This is line 1.</PRE></BLOCKQUOTE><P>Perl also has the <TT>printf()</TT>fuNCtion which lets you be more precise in how things are printedout. The syntax for <TT>printf()</TT>looks like this:<BLOCKQUOTE><PRE>printf FILE_HANDLE (FORMAT_STRING, LIST)</PRE></BLOCKQUOTE><P>Like <TT>print()</TT>, the defaultfile handle is <TT>STDOUT</TT>. The<TT>FORMAT_STRING</TT> parameter controlswhat is printed and how it looks. For simple cases, the formattingparameter looks identical to the list that is passed to <TT>printf()</TT>.For example:<P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Create two variables to hold costs for January and February.<BR>Print the cost variables using variable interpolation. Noticethat the dollar sign needs to be preceded by the backslash toavoid interpolation that you don't want.</I></BLOCKQUOTE><BLOCKQUOTE><PRE>$januaryCost = 123.34;$februaryCost = 23345.45;printf("January = \$$januaryCost\n");printf("February = \$$februaryCost\n");</PRE></BLOCKQUOTE><P>This program displays:<BLOCKQUOTE><PRE>January = $123.34February = $23345.45</PRE></BLOCKQUOTE><P>In this example, only one parameter is passed to the <TT>printf()</TT>fuNCtion-the formatting string. Because the formatting stringis eNClosed in double quotes, variable interpolation will takeplace just like for the <TT>print()</TT>fuNCtion.<P>This display is not good enough for a report because the decimalpoints of the numbers do not line up. You can use the formattingspecifiers shown in Table 9.5 together with the modifiers shownin Table 9.6 to solve this problem.<BR><P><B>Table 9.5 Format Specifiers for the printf() FuNCtion</B><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -