.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" ======================================================================== .\" .IX Title "Paranoid::IO::Line 3pm" .TH Paranoid::IO::Line 3pm "2016-12-25" "perl v5.24.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Paranoid::IO::Line \- Paranoid Line\-based I/O functions .SH "VERSION" .IX Header "VERSION" \&\f(CW$Id:\fR lib/Paranoid/IO/Line.pm, 2.04 2016/09/19 15:00:25 acorliss Exp $ .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Paranoid::IO::Line; \& \& PIOMAXLNSIZE = 4096; \& \& $nlines = sip($filename, @lines); \& $nlines = sip($filename, @lines, 1); \& $nlines = tailf($filename, @lines); \& $nlines = tailf($filename, @lines, 1); \& $nlines = tailf($filename, @lines, 1, \-100); \& \& piolClose($filename); \& \& $nlines = slurp($filename, @lines); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module extends and leverages Paranoid::IO's capabilities with an eye towards line-based text files, such as log files. It does so while maintaining a paranoid stance towards I/O. For that reason the functions here only work on limited chunks of data at a time, both in terms of maximum memory kept in memory at a time and the maximum record length. Paranoid::IO provides \fI\s-1PIOMAXFSIZE\s0\fR which controls the former, but this module provides \&\fI\s-1PIOMAXLNSIZE\s0\fR which controls the latter. .PP Even with the paranoid slant of these functions they should really be treated as convenience functions which can simplify higher level code without incurring any significant risk to the developer or system. They inherit not only opportunistic I/O but platform-agnostic record separators via internal use of \fIpchomp\fR from Paranoid::Input. .PP \&\fB\s-1NOTE:\s0\fR while this does build off the foundation provided by Paranoid::IO it is important to note that you should not work on the same files using :'s functions while also using the functions in this module. While the former works from raw I/O the latter has to manage buffers in order to identify record boundaries. If you were to, say, \fIsip\fR from a file, then \&\fIpread\fR or \fIpseek\fR elsewhere it would render those buffers not only useless, but corrupt. This is important to note since the functions here do leverage the file handle caching features provided by \fIpopen\fR. .PP It should also be noted that since we're anticipating line-based records we expect every line, even the last line in a file, to be properly terminated with a record separator (new line sequence). .PP As with all Paranoid modules string descriptions of errors can be retrieved from Paranoid::ERROR as they occur. .SH "SUBROUTINES/METHODS" .IX Header "SUBROUTINES/METHODS" .SS "\s-1PIOMAXLNSIZE\s0" .IX Subsection "PIOMAXLNSIZE" The valute returned/set by this lvalue function is the maximum line length supported by functions like \fBsip\fR (documented below). Unless explicitly set this defaults to 2KB. Any lines found which exceed this are discarded. .SS "sip" .IX Subsection "sip" .Vb 2 \& $nlines = sip($filename, @lines); \& $nlines = sip($filename, @lines, 1); .Ve .PP This function allows you to read a text file into memory in chunks, the lines of which are placed into the passed array reference. The chunks are read in at up to \s-1PIOMAXFSIZE\s0 in size at a time. File locking is used and autochomping is also supported. .PP This returns the number of lines extracted or boolean false if any errors occurred, such as lines exceeding \fI\s-1PIOMAXLNSIZE\s0\fR or other I/O errors. If there were no errors but also no content it will return \fB0 but true\fR, which will satisfy boolean tests. .PP The passed array is always purged prior to execution. This can potentially help differentiate types of errors: .PP .Vb 1 \& $nlines = sip($filename, @lines); \& \& warn "successfully extracted lines" \& if $nlines and scalar @lines; \& warn "no errors, but no lines" \& if $nlines and ! scalar @lines; \& warn "line length exceeded on some lines" \& if !$nlines and scalar @lines; \& warn "I/O errors or all lines exceeded line length" \& if !$nlines and ! scalar @lines; .Ve .PP Typically, if all one cares about is extracting good lines and discarding bad ones all you need is: .PP .Vb 1 \& warn "good to go" if scalar @lines or $nlines; \& \& # or, more likely: \& if (@lines) { \& # process input... \& } .Ve .PP \&\fB\s-1NOTE:\s0\fR \fIsip\fR does try to check the file stat with every call. This allows us to automatically flush buffers and reopen files in the event that the file you're sipping from was truncated, deleted, or overwritten. .SS "nlsip" .IX Subsection "nlsip" .Vb 2 \& $nlines = nlsip($filename, @lines); \& $nlines = nlsip($filename, @lines, 1); .Ve .PP A very thin wrapper for \fIsip\fR that disables file locking. .SS "tailf" .IX Subsection "tailf" .Vb 3 \& $nlines = tailf($filename, @lines); \& $nlines = tailf($filename, @lines, 1); \& $nlines = tailf($filename, @lines, 1, \-100); .Ve .PP The only difference between this function and \fBsip\fR is that tailf opens the file and immediately seeks to the end. If an optional fourth argument is passed it will seek backwards to extract and return that number of lines (if possible). Depending on the number passed one must be prepared for enough memory to be allocated to store \fB\s-1PIOMAXLNSIZE\s0\fR * that number. If no number is specified it is assumed to be \fB\-10\fR. Specifying this argument on a file already opened by \fIsip\fR or \fItailf\fR will have no effect. .PP Return values are identical to \fIsip\fR. .SS "nltailf" .IX Subsection "nltailf" .Vb 3 \& $nlines = nltailf($filename, @lines); \& $nlines = nltailf($filename, @lines, \-100); \& $nlines = nltailf($filename, @lines, \-100, 1); .Ve .PP A very thin wrapper for \fItailf\fR that disables file locking. .SS "slurp" .IX Subsection "slurp" .Vb 2 \& $nlines = slurp($filename, @lines); \& $nlines = slurp($filename, @lines, 1); .Ve .PP This function is essentially another wrapper for \fIsip\fR, but with some different behavior. While \fIsip\fR was written from the expectation that the developer would be either working on chunks from a very large file or a file that may grow while being accessed. \fIslurp\fR, on the other hand, expects to work exclusively on small files that can safely fit into memory. It also sees no need to cache file handles since all operations will subsequently be done in memory. .PP Files with slurp are explicitly closed after the read. All the normal safeguards apply: \fI\s-1PIOMAXFSIZE\s0\fR is the largest amount of data that will be read into memory, and all lines must be within \fI\s-1PIOMAXLNSIZE\s0\fR. .SS "nlslurp" .IX Subsection "nlslurp" .Vb 2 \& $nlines = nlslurp($filename, @lines); \& $nlines = nlslurp($filename, @lines, 1); .Ve .PP A very thin wrapper for \fIslurp\fR that disables file locking. .SS "piolClose" .IX Subsection "piolClose" .Vb 1 \& $rv = piolClose($filename); .Ve .PP This closes all file handles and deletes any existing buffers. Works indiscriminatley and returns the exit value of \fIpclose\fR. .SH "DEPENDENCIES" .IX Header "DEPENDENCIES" .IP "o" 4 .IX Item "o" Fcntl .IP "o" 4 .IX Item "o" Paranoid .IP "o" 4 .IX Item "o" Paranoid::Debug .IP "o" 4 .IX Item "o" Paranoid::Input .IP "o" 4 .IX Item "o" Paranoid::IO .SH "BUGS AND LIMITATIONS" .IX Header "BUGS AND LIMITATIONS" While all of these functions will just as happily accept file handles as well as file names doing will almost certainly cause any number of bugs. Beyond the inherited Paranoid::IO issues (like not getting the fork-safe features for any file handle opened directly by the developer) there are other issues. Buffers, for instance, can only be managed by one consistent name, there is no way to correlate them and make them interchangeable. There are other subtleties as well, but there is no need to detail them all. .PP Suffice it to say that when using this module one should only use file names, and use them consistently. .SH "AUTHOR" .IX Header "AUTHOR" Arthur Corliss (corliss@digitalmages.com) .SH "LICENSE AND COPYRIGHT" .IX Header "LICENSE AND COPYRIGHT" This software is licensed under the same terms as Perl, itself. Please see http://dev.perl.org/licenses/ for more information. .PP (c) 2005 \- 2015, Arthur Corliss (corliss@digitalmages.com)