Learning Perl: 5.7. Opening a Filehandle

5.7. Opening a Filehandle You've seen that Perl provides three filehandlesSTDIN,STDOUT,and STDERRwhich are automatically open to files or devices established by the program's parent process (probably the shell). When you need other filehandles,use the open operator to tell Perl to ask the operating system to open the connection between your program and the outside world. Here are some examples: open CONFIG,"dino"; open CONFIG," fred"; open LOG,">>logfile"; The first one opens a filehandle called CONFIG to a file called dino. That is,the (existing) file dino will be opened and whatever it holds will come into our program through the filehandle named CONFIG. This is similar to the way that data from a file could come in through STDIN if the command line had a shell redirection like $selected_output"; Note the space after the greater-than sign. Perl ignores this,[] but it keeps unexpected things from happening if $selected_output were ">passwd",for example,which would make an append instead of a write. [] Yes,this means that if your filename were to have leading whitespace,Perl would ignore that,too. See perlfunc and perlopentut if you're worried about this. In modern versions of Perl (starting with Perl 5.6),you can use a "three-argument" open: open CONFIG,"<","dino"; open BEDROCK,">",$file_name; open LOG,">>",&logfile_name( ); The advantage here is that Perl never confuses the mode (the second argument) with some part of the filename (the third argument),which has nice advantages for security.[*] However,if you need your Perl to be backward compatible to older Perl versions (such as when you are contributing to the CPAN),avoid these forms or mark your Perl sources as being compatible only with newer Perls.[] [*] The disadvantage for security is that,presumably,you're letting a possibly malicious user inject possibly malicious characters into the delicate workings of your innocent program. Once you learn about regular expressions (starting in Chapter 7),you'll be able to use those to enforce some sanity checks on user input. And if your program has possibly malicious users,read up on Perl's helpful security features in the Alpaca book,in the perlsec manpage,or both. [] Via use 5.6,for example. We'll see how to use these filehandles later in this chapter. 5.7.1. Bad Filehandles Perl can't open a file all by itself. Like any other programming language,Perl merely asks the operating system to open a file. Of course,the operating system may refuse because of permission settings,an incorrect filename,or other reasons. If you try to read from a bad filehandle (that is,a filehandle that isn't properly open),you'll see an immediate end-of-file. (With the I/O methods we'll see in this chapter,end-of-file will be indicated by undef in a scalar context or an empty list in a list context.) If you try to write to a bad filehandle,the data is silently discarded. Fortunately,these dire consequences are avoidable. First of all,if we ask for warnings with -w or the warnings pragma,Perl will generally be able to tell us with a warning when it sees that we're using a bad filehandle. But even without that,open always tells us if it succeeded or failed by returning true for success or false for failure. You could write code like this: my $success = open LOG,">>logfile"; # capture the return value if ( ! $success) { # The open failed . . . } You could do it like that,but there's another way that we'll see in the next section. 5.7.2. Closing a Filehandle When you are finished with a filehandle,you may close it with the close operator like this: close BEDROCK; Closing a filehandle tells Perl to inform the operating system that we're all done with the given data stream,so any last output data should be written to disk in case someone is waiting for it.[*] Perl will automatically close a filehandle if you reopen it (that is,if you reuse the filehandle name in a new open) or if you exit the program.[] [*] If you know much about I/O systems,you'll know there's more to the story. Generally,when a filehandle is closed,here's what happens. If there's input remaining in a file,it's ignored. If there's input remaining in a pipeline,the writing program may get a signal that the pipeline is closed. If there's output going to a file or pipeline,the buffer is flushed (that is,pending output is sent on its way). If the filehandle had a lock,the lock is released. See your system's I/O documentation for further details. [] Any exit from the program will close all filehandles,but if Perl breaks,pending output buffers won't get flushed. That is to say,if you accidentally crash your program by dividing by zero,Perl will still run and ensure that data you've written will get output. But if Perl can't run (because you ran out of memory or caught an unexpected signal),the last few pieces of output may not be written to disk. Usually,this isn't a big issue. Because of this,many Perl programs don't bother with close. But it's there if you want to be tidy,with one close for every open. In general,it's best to close each filehandle soon after you're done with it,though the end of the program often arrives soon enough.[] [] Closing a filehandle will flush any output buffers and release any locks on the file. Since someone else may be waiting for those things,a long-running program should close each filehandle as soon as possible. But many of our programs will take only one or two seconds to run to completion,so this may not matter. Closing a filehandle also releases possibly limited resources,so it's more than being tidy. ";>

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...