1IO::InSitu(3) User Contributed Perl Documentation IO::InSitu(3)
2
3
4
6 IO::InSitu - Avoid clobbering files opened for both input and output
7
9 This document describes IO::InSitu version 0.0.1
10
12 use IO::InSitu;
13
14 my ($in, $out) = open_rw($infile_name, $outfile_name);
15
16 for my $line (<$in>) {
17 $line =~ s/foo/bar/g;
18 print {$out} $line;
19 }
20
22 When users want to do in-situ processing on a file, they often specify
23 it as both the input and output file:
24
25 > myapp -i sample_data -o sample_data -op=normalize
26
27 But, if the "-i" and "-o" flags are processed independently, the
28 program will usually open the file for input, open it again for output
29 (at which point the file will be truncated to zero length), and then
30 attempt to read in the first line of the now-empty file:
31
32 # Open both filehandles...
33 use Fatal qw( open );
34 open my $src, '<', $source_file;
35 open my $dest, '>', $destination_file;
36
37 # Read, process, and output data, line-by-line...
38 while (my $line = <$src>) {
39 print {$dest} transform($line);
40 }
41
42 Not only does this not perform the requested transformation on the
43 file, it also destroys the original data. Fortunately, this problem is
44 extremely easy to avoid: just make sure that you unlink the output file
45 before you open it:
46
47 # Open both filehandles...
48 use Fatal qw( open );
49 open my $src, '<', $source_file;
50 unlink $destination_file;
51 open my $dest, '>', $destination_file;
52
53 # Read, process, and output data, line-by-line...
54 while (my $line = <$src>) {
55 print {$dest} transform($line);
56 }
57
58 If the input and output files are different, unlinking the output file
59 merely removes a file that was about to be rewritten anyway. Then the
60 second open simply recreates the output file, ready for writing.
61
62 If the two filenames actually refer to a single in-situ file, unlinking
63 the output filename removes that filename from its directory, but
64 doesn't remove the file itself from the filesystem. The file is already
65 open through the filehandle in $input, so the filesystem will preserve
66 the unlinked file until that input filehandle is closed. The second
67 open then creates a new version of the in-situ file, ready for writing.
68
69 The only limitation of this technique is that it changes the inode of
70 any in-situ file . That can be a problem if the file has any hard-
71 linked aliases, or if other applications are identifying the file by
72 its inode number. If either of those situations is possible, you can
73 preserve the in-situ file's inode by using the "open_rw()" subroutine
74 that is exported from this module:
75
76 # Open both filehandles...
77 use IO::InSitu;
78 my ($src, $dest) = open_rw($source_file, $destination_file);
79
80 # Read, process, and output data, line-by-line...
81 while (my $line = <$src>) {
82 print {$dest} transform($line);
83 }
84
86 "($in_fh, $out_fh) = open_rw($infile_name, $outfile_name, \%options)"
87 "($in_fh, $out_fh) = open_rw($in_out_file_name, \%options)"
88 The "open_rw()" subroutine takes the names of two files: one to be
89 opened for reading, the other for writing. If you only give it a
90 single filename, it opens that file for both reading and writing.
91
92 It returns a list of two filehandles, opened to those two files.
93 However, if the filename(s) refer to the same file, "open_rw()"
94 first makes a temporary copy of the file, which it opens for input.
95 It then opens the original file for output. In such cases, when the
96 input filehandle is eventually closed, IO::InSitu arranges for the
97 temporary file to be automatically deleted.
98
99 This approach preserves the original file's inode, but at the cost
100 of making a temporary copy of the file. The name of the temporary
101 is usually formed by appending '.bak' to the original filename, but
102 this can be altered, by passing the 'tmp' option to "open_rw()":
103
104 my ($src, $dest) = open_rw($source, $destination, {tmp=>\&temp_namer});
105
106 The 'tmp' option expects to be passed a reference to a subroutine.
107 That subroutine will be called and passed the name of the input
108 file. It is expected to return the name of the back-up file. For
109 example:
110
111 sub tmp_namer {
112 my ($input_file) = @_;
113
114 return "$input_file.orig";
115 }
116
118 "Usage: open_rw( $in_filename, $out_filename, \%options )"
119 You called "open_rw()" with less than two arguments, or more than
120 three. Pass the function two filenames, and (optionally) a
121 reference to any options.
122
123 "Can't open non-existent input file '%s'"
124 You specified an input file that does not exist on the filesystem.
125 Usually caused by a misspelling, or an incorrect file path.
126
127 "Can't open input file '%s'"
128 You specified an input file that exists on the filesystem but could
129 not be opened for reading. Usually caused by insufficient file
130 permissions.
131
132 "Can't open copy of input file '%s'"
133 The module was unable to create (or access) its back-up copy of the
134 input file. This is usually caused by insufficient file permissions
135 on the directory where the back-up is supposed to be written.
136
137 "Can't open output file '%s'"
138 You specified an output file that could not be opened for writing.
139 This usually means the directory into which the output file was to
140 be placed is non-existent or you don't have write permission to the
141 directory or the output file.
142
144 IO::InSitu requires no configuration files or environment variables.
145
147 None.
148
150 None reported.
151
153 No bugs have been reported.
154
155 Please report any bugs or feature requests to
156 "bug-io-insitu@rt.cpan.org", or through the web interface at
157 <http://rt.cpan.org>.
158
160 Damian Conway "<DCONWAY@cpan.org>"
161
163 Copyright (c) 2005, Damian Conway "<DCONWAY@cpan.org>". All rights
164 reserved.
165
166 This module is free software; you can redistribute it and/or modify it
167 under the same terms as Perl itself.
168
170 BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
171 FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
172 WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
173 PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
174 EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
175 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
176 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
177 YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
178 NECESSARY SERVICING, REPAIR, OR CORRECTION.
179
180 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
181 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
182 REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
183 TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
184 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
185 SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
186 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
187 FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
188 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
189 DAMAGES.
190
191
192
193perl v5.32.0 2020-07-28 IO::InSitu(3)