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

📄 perlfaq5.1

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 1
📖 第 1 页 / 共 5 页
字号:
Newer versions of File::Copy export a \fImove()\fR function..Sh "How can I lock a file?".IX Xref "lock file, lock flock".IX Subsection "How can I lock a file?"Perl's builtin \fIflock()\fR function (see perlfunc for details) will call\&\fIflock\fR\|(2) if that exists, \fIfcntl\fR\|(2) if it doesn't (on perl version 5.004 andlater), and \fIlockf\fR\|(3) if neither of the two previous system calls exists.On some systems, it may even use a different form of native locking.Here are some gotchas with Perl's \fIflock()\fR:.IP "1." 4Produces a fatal error if none of the three system calls (or theirclose equivalent) exists..IP "2." 4\&\fIlockf\fR\|(3) does not provide shared locking, and requires that thefilehandle be open for writing (or appending, or read/writing)..IP "3." 4Some versions of \fIflock()\fR can't lock files over a network (e.g. on \s-1NFS\s0 filesystems), so you'd need to force the use of \fIfcntl\fR\|(2) when you build Perl.But even this is dubious at best.  See the flock entry of perlfuncand the \fI\s-1INSTALL\s0\fR file in the source distribution for information onbuilding Perl to do this..SpTwo potentially non-obvious but traditional flock semantics are thatit waits indefinitely until the lock is granted, and that its locks are\&\fImerely advisory\fR.  Such discretionary locks are more flexible, butoffer fewer guarantees.  This means that files locked with \fIflock()\fR maybe modified by programs that do not also use \fIflock()\fR.  Cars that stopfor red lights get on well with each other, but not with cars that don'tstop for red lights.  See the perlport manpage, your port's specificdocumentation, or your system-specific local manpages for details.  It'sbest to assume traditional behavior if you're writing portable programs.(If you're not, you should as always feel perfectly free to writefor your own system's idiosyncrasies (sometimes called \*(L"features\*(R").Slavish adherence to portability concerns shouldn't get in the way ofyour getting your job done.).SpFor more information on file locking, see also\&\*(L"File Locking\*(R" in perlopentut if you have it (new for 5.6)..ie n .Sh "Why can't I just open(\s-1FH\s0, "">file.lock"")?".el .Sh "Why can't I just open(\s-1FH\s0, ``>file.lock'')?".IX Xref "lock, lockfile race condition".IX Subsection "Why can't I just open(FH, >file.lock)?"A common bit of code \fB\s-1NOT\s0 \s-1TO\s0 \s-1USE\s0\fR is this:.PP.Vb 2\&        sleep(3) while \-e "file.lock";  # PLEASE DO NOT USE\&        open(LCK, "> file.lock");               # THIS BROKEN CODE.Ve.PPThis is a classic race condition: you take two steps to do somethingwhich must be done in one.  That's why computer hardware provides anatomic test-and-set instruction.   In theory, this \*(L"ought\*(R" to work:.PP.Vb 2\&        sysopen(FH, "file.lock", O_WRONLY|O_EXCL|O_CREAT)\&                or die "can\*(Aqt open  file.lock: $!";.Ve.PPexcept that lamentably, file creation (and deletion) is not atomicover \s-1NFS\s0, so this won't work (at least, not every time) over the net.Various schemes involving \fIlink()\fR have been suggested, butthese tend to involve busy-wait, which is also less than desirable..Sh "I still don't get locking.  I just want to increment the number in the file.  How can I do this?".IX Xref "counter file, counter".IX Subsection "I still don't get locking.  I just want to increment the number in the file.  How can I do this?"Didn't anyone ever tell you web-page hit counters were useless?They don't count number of hits, they're a waste of time, and they serveonly to stroke the writer's vanity.  It's better to pick a random number;they're more realistic..PPAnyway, this is what you can do if you can't help yourself..PP.Vb 8\&        use Fcntl qw(:DEFAULT :flock);\&        sysopen(FH, "numfile", O_RDWR|O_CREAT)   or die "can\*(Aqt open numfile: $!";\&        flock(FH, LOCK_EX)                               or die "can\*(Aqt flock numfile: $!";\&        $num = <FH> || 0;\&        seek(FH, 0, 0)                           or die "can\*(Aqt rewind numfile: $!";\&        truncate(FH, 0)                                  or die "can\*(Aqt truncate numfile: $!";\&        (print FH $num+1, "\en")                  or die "can\*(Aqt write numfile: $!";\&        close FH                                         or die "can\*(Aqt close numfile: $!";.Ve.PPHere's a much better web-page hit counter:.PP.Vb 1\&        $hits = int( (time() \- 850_000_000) / rand(1_000) );.Ve.PPIf the count doesn't impress your friends, then the code might.  :\-).Sh "All I want to do is append a small amount of text to the end of a file.  Do I still have to use locking?".IX Xref "append file, append".IX Subsection "All I want to do is append a small amount of text to the end of a file.  Do I still have to use locking?"If you are on a system that correctly implements \fIflock()\fR and you use theexample appending code from \*(L"perldoc \-f flock\*(R" everything will be \s-1OK\s0even if the \s-1OS\s0 you are on doesn't implement append mode correctly (ifsuch a system exists.) So if you are happy to restrict yourself to OSsthat implement \fIflock()\fR (and that's not really much of a restriction)then that is what you should do..PPIf you know you are only going to use a system that does correctlyimplement appending (i.e. not Win32) then you can omit the \fIseek()\fR fromthe code in the previous answer..PPIf you know you are only writing code to run on an \s-1OS\s0 and filesystem thatdoes implement append mode correctly (a local filesystem on a modernUnix for example), and you keep the file in block-buffered mode and youwrite less than one buffer-full of output between each manual flushingof the buffer then each bufferload is almost guaranteed to be written tothe end of the file in one chunk without getting intermingled withanyone else's output. You can also use the \fIsyswrite()\fR function which issimply a wrapper around your systems \fIwrite\fR\|(2) system call..PPThere is still a small theoretical chance that a signal will interruptthe system level \fIwrite()\fR operation before completion.  There is also apossibility that some \s-1STDIO\s0 implementations may call multiple systemlevel \fIwrite()\fRs even if the buffer was empty to start.  There may be somesystems where this probability is reduced to zero..Sh "How do I randomly update a binary file?".IX Xref "file, binary patch".IX Subsection "How do I randomly update a binary file?"If you're just trying to patch a binary, in many cases something assimple as this works:.PP.Vb 1\&        perl \-i \-pe \*(Aqs{window manager}{window mangler}g\*(Aq /usr/bin/emacs.Ve.PPHowever, if you have fixed sized records, then you might do something morelike this:.PP.Vb 9\&        $RECSIZE = 220; # size of record, in bytes\&        $recno   = 37;  # which record to update\&        open(FH, "+<somewhere") || die "can\*(Aqt update somewhere: $!";\&        seek(FH, $recno * $RECSIZE, 0);\&        read(FH, $record, $RECSIZE) == $RECSIZE || die "can\*(Aqt read record $recno: $!";\&        # munge the record\&        seek(FH, \-$RECSIZE, 1);\&        print FH $record;\&        close FH;.Ve.PPLocking and error checking are left as an exercise for the reader.Don't forget them or you'll be quite sorry..Sh "How do I get a file's timestamp in perl?".IX Xref "timestamp file, timestamp".IX Subsection "How do I get a file's timestamp in perl?"If you want to retrieve the time at which the file was lastread, written, or had its meta-data (owner, etc) changed,you use the \fB\-A\fR, \fB\-M\fR, or \fB\-C\fR file test operations asdocumented in perlfunc.  These retrieve the age of thefile (measured against the start-time of your program) indays as a floating point number. Some platforms may not haveall of these times.  See perlport for details. Toretrieve the \*(L"raw\*(R" time in seconds since the epoch, youwould call the stat function, then use \fIlocaltime()\fR,\&\fIgmtime()\fR, or \fIPOSIX::strftime()\fR to convert this intohuman-readable form..PPHere's an example:.PP.Vb 3\&        $write_secs = (stat($file))[9];\&        printf "file %s updated at %s\en", $file,\&        scalar localtime($write_secs);.Ve.PPIf you prefer something more legible, use the File::stat module(part of the standard distribution in version 5.004 and later):.PP.Vb 5\&        # error checking left as an exercise for reader.\&        use File::stat;\&        use Time::localtime;\&        $date_string = ctime(stat($file)\->mtime);\&        print "file $file updated at $date_string\en";.Ve.PPThe \fIPOSIX::strftime()\fR approach has the benefit of being,in theory, independent of the current locale.  See perllocalefor details..Sh "How do I set a file's timestamp in perl?".IX Xref "timestamp file, timestamp".IX Subsection "How do I set a file's timestamp in perl?"You use the \fIutime()\fR function documented in \*(L"utime\*(R" in perlfunc.By way of example, here's a little program that copies theread and write times from its first argument to all the restof them..PP.Vb 6\&        if (@ARGV < 2) {\&                die "usage: cptimes timestamp_file other_files ...\en";\&                }\&        $timestamp = shift;\&        ($atime, $mtime) = (stat($timestamp))[8,9];\&        utime $atime, $mtime, @ARGV;.Ve.PPError checking is, as usual, left as an exercise for the reader..PPThe perldoc for utime also has an example that has the sameeffect as \fItouch\fR\|(1) on files that \fIalready exist\fR..PPCertain file systems have a limited ability to store the timeson a file at the expected level of precision.  For example, the\&\s-1FAT\s0 and \s-1HPFS\s0 filesystem are unable to create dates on files witha finer granularity than two seconds.  This is a limitation ofthe filesystems, not of \fIutime()\fR..Sh "How do I print to more than one file at once?".IX Xref "print, to multiple files".IX Subsection "How do I print to more than one file at once?"To connect one filehandle to several output filehandles,you can use the IO::Tee or Tie::FileHandle::Multiplex modules..PPIf you only have to do this once, you can print individuallyto each filehandle..PP.Vb 1\&        for $fh (FH1, FH2, FH3) { print $fh "whatever\en" }.Ve.Sh "How can I read in an entire file all at once?".IX Xref "slurp file, slurping".IX Subsection "How can I read in an entire file all at once?"You can use the File::Slurp module to do it in one step..PP.Vb 1\&        use File::Slurp;\&\&        $all_of_it = read_file($filename); # entire file in scalar\&        @all_lines = read_file($filename); # one line perl element.Ve.PPThe customary Perl approach for processing all the lines in a file is todo so one line at a time:.PP.Vb 6\&        open (INPUT, $file)     || die "can\*(Aqt open $file: $!";\&        while (<INPUT>) {\&                chomp;\&                # do something with $_\&                }\&        close(INPUT)            || die "can\*(Aqt close $file: $!";.Ve.PPThis is tremendously more efficient than reading the entire file intomemory as an array of lines and then processing it one element at a time,which is often\*(--if not almost always\*(--the wrong approach.  Wheneveryou see someone do this:.PP.Vb 1\&        @lines = <INPUT>;.Ve.PPyou should think long and hard about why you need everything loaded atonce.  It's just not a scalable solution.  You might also find it morefun to use the standard Tie::File module, or the DB_File module's\&\f(CW$DB_RECNO\fR bindings, which allow you to tie an array to a file so thataccessing an element the array actually accesses the correspondingline in the file..PPYou can read the entire filehandle contents into a scalar..PP.Vb 5\&        {\&        local(*INPUT, $/);\&        open (INPUT, $file)     || die "can\*(Aqt open $file: $!";\&        $var = <INPUT>;\&        }.Ve.PPThat temporarily undefs your record separator, and will automaticallyclose the file at block exit.  If the file is already open, just use this:.PP.Vb 1\&        $var = do { local $/; <INPUT> };.Ve.PPFor ordinary files you can also use the read function..PP.Vb 1\&        read( INPUT, $var, \-s INPUT );.Ve.PPThe third argument tests the byte size of the data on the \s-1INPUT\s0 filehandleand reads that many bytes into the buffer \f(CW$var\fR..Sh "How can I read in a file by paragraphs?".IX Xref "file, reading by paragraphs".IX Subsection "How can I read in a file by paragraphs?"Use the \f(CW$/\fR variable (see perlvar for details).  You can eitherset it to \f(CW""\fR to eliminate empty paragraphs (\f(CW"abc\en\en\en\endef"\fR,for instance, gets treated as two paragraphs and not three), or\&\f(CW"\en\en"\fR to accept empty paragraphs..PPNote that a blank line must have no blanks in it.  Thus\&\f(CW"fred\en\ \enstuff\en\en"\fR is one paragraph, but \f(CW"fred\en\enstuff\en\en"\fR is two..Sh "How can I read a single character from a file?  From the keyboard?".IX Xref "getc file, reading one character at a time".IX Subsection "How can I read a single character from a file?  From the keyboard?"You can use the builtin \f(CW\*(C`getc()\*(C'\fR function for most filehandles, butit won't (easily) work on a terminal device.  For \s-1STDIN\s0, either usethe Term::ReadKey module from \s-1CPAN\s0 or use the sample code in\&\*(L"getc\*(R" in perlfunc..PPIf your system supports the portable operating system programminginterface (\s-1POSIX\s0), you can use the following code, which you'll noteturns off echo processing as well..PP.Vb 10\&        #!/usr/bin/perl \-w\&        use strict;\&        $| = 1;\&        for (1..4) {\&                my $got;\&                print "gimme: ";\&                $got = getone();\&                print "\-\-> $got\en";\&                }\&    exit;\&\&        BEGIN {\&        use POSIX qw(:termios_h);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -