summaryrefslogtreecommitdiff
path: root/README.pod
blob: 698ee9db0196897221aa0121a6be64dd198d77a4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
=pod

=encoding UTF-8

=head1 NAME

File::Flat - Implements a flat filesystem

=head1 VERSION

version 1.06

=head1 DESCRIPTION

=for stopwords FSI.pm VMS canExecute canOpen canRead canReadWrite canRemove canWrite cp getAppendHandle getReadHandle getReadWriteHandle getWriteHandle isaBinary isaDirectory isaFile isaText makeDirectory

File::Flat implements a flat filesystem. A flat filesystem is a filesystem in
which directories do not exist. It provides an abstraction over any normal
filesystem which makes it appear as if directories do not exist. In effect,
it will automatically create directories as needed. This is create for things
like install scripts and such, as you never need to worry about the existence
of directories, just write to a file, no matter where it is.

=head2 Comprehensive Implementation

The implementation of File::Flat is extremely comprehensive in scope. It has
methods for all standard file interaction tasks, the -X series of tests, and
some other things, such as slurp.

All methods are statically called, for example, to write some stuff to a file.

  use File::Flat;
  File::Flat->write( 'filename', 'file contents' );

=head2 Use of other modules

File::Flat tries to use more task orientated modules wherever possible. This
includes the use of L<File::Copy>, L<File::Copy::Recursive>, L<File::Remove>
and others. These are mostly loaded on-demand.

=head2 Pruning and $AUTO_PRUNE

"Pruning" is a technique where empty directories are assumed to be useless,
and thus empty removed whenever one is created. Thus, when some other task
has the potential to leave an empty directory, it is checked and deleted if
it is empty.

By default File::Flat does not prune, and pruning must be done explicitly,
via either the L<File::Flat/prune> method, or by setting the second
argument to the L<File::Flat/remove> method to be true.

However by setting the global C<$AUTO_PRUNE> variable to true, File::Flat
will automatically prune directories at all times. You should generally use
this locally, such as in the following example.

  #!/usr/bin/perl
  
  use strict;
  use File::Flat;
  
  delete_files(@ARGV);
  exit();
  
  # Recursively delete and prune all files provided on the command line
  sub delete_files {
  	local $File::Flat::AUTO_PRUNE = 1;
  	foreach my $file ( @_ ) {
  		File::Flat->remove( $file ) or die "Failed to delete $file";
  	}
  }

=head2 Non-Unix platforms

As of version 0.97 File::Flat should work correctly on Win32. Other
platforms (such as VMS) are believed to work, but require confirmation.

=head1 METHODS

=head2 exists $filename 

Tests for the existence of the file.
This is an exact duplicate of the -e function.

=head2 isaFile $filename

Tests whether C<filename> is a file.
This is an exact duplicate of the -f function.

=head2 isaDirectory $filename

Test whether C<filename> is a directory.
This is an exact duplicate of the -d function.

=head2 canRead $filename

Does the file or directory exist, and can we read from it.

=head2 canWrite $filename

Does the file or directory exist, and can we write to it 
B<OR> can we create the file or directory.

=head2 canReadWrite $filename

Does a file or directory exist, and can we both read and write it.

=head2 canExecute $filename

Does a file or directory exist, and can we execute it.

=head2 canOpen $filename

Is this something we can open a filehandle to. Returns true if filename
exists, is a file, and we can read from it.

=head2 canRemove $filename

Can we remove the file or directory.

=head2 isaText $filename

Does the file C<filename> exist, and is it a text file.

=head2 isaBinary $filename

Does the file C<filename> exist, and is it a binary file.

=head2 fileSize $filename

If the file exists, returns its size in bytes.
Returns undef if the file does not exist.

=head2 open [ $mode, ] $filename

Rough analogue of the open function, but creates directories on demand
as needed. Supports most of the normal options to the normal open function.

In the single argument form, it takes modes in the form [mode]filename. For
example, all the following are valid.

  File::Flat->open( 'filename' );
  File::Flat->open( '<filename' );
  File::Flat->open( '>filename' );
  File::Flat->open( '>>filename' );
  File::Flat->open( '+<filename' );

In the two argument form, it takes the following

  File::Flat->open( '<', 'filename' );
  File::Flat->open( '>', 'filename' );
  File::Flat->open( '>>', 'filename' );
  File::Flat->open( '+<', 'filename' );

It does not support the more esoteric forms of open, such us opening to a pipe
or other such things.

On successfully opening the file, it returns it as an IO::File object.
Returns undef on error.

=head2 getReadHandle $filename

The same as File::Flat->open( '<', 'filename' )

=head2 getWriteHandle $filename

The same as File::Flat->open( '>', 'filename' )

=head2 getAppendHandle $filename

The same as File::Flat->open( '>>', 'filename' )

=head2 getReadWriteHandle $filename

The same as File::Flat->open( '+<', 'filename' )

=head2 read $filename

Opens and reads in an entire file, chomping as needed.

In array context, it returns an array containing each line of the file.
In scalar context, it returns a reference to an array containing each line of
the file. It returns undef on error.

=head2 slurp $filename

The C<slurp> method 'slurps' a file in. That is it attempts to read the entire
file into a variable in as quick and memory efficient method as possible.

On success, returns a reference to a scalar, containing the entire file.
Returns undef on error.

=head2 write $filename, ( $content | \$content | \@content )

The C<write> method is the main method for writing content to a file.
It takes two arguments, the location to write to, and the content to write, 
in several forms.

If the file already exists, it will be clobbered before writing starts.
If the file doesn't exists, the file and any directories will be created as
needed.

Content can be provided in three forms. The contents of a scalar argument will
be written directly to the file. You can optionally pass a reference to the 
scalar. This is recommended when the file size is bigger than a few thousand
characters, is it does not duplicate the file contents in memory.
Alternatively, you can pass the content as a reference to an array containing
the contents. To ensure uniformity, C<write> will add a newline to each line,
replacing any existing newline as needed.

Returns true on success, and undef on error.

=head2 append $filename, ( $content | \$content | \@content )

This method is the same as C<write>, except that it appends to the end of 
an existing file ( or creates the file as needed ).

This is the method you should be using to write to log files, etc.

=head2 overwrite $filename, ( $content | \$content | \@content )

Performs an atomic write over a file. It does this by writing to a temporary
file, and moving the completed file over the top of the existing file ( or
creating a new file as needed ). When writing to a file that is on the same
partition as /tmp, this should always be atomic. 

This method otherwise acts the same as C<write>.

=head2 copy $source, $target

The C<copy> method attempts to copy a file or directory from the source to
the target. New directories to contain the target will be created as needed.

For example C<<File::Flat->( './this', './a/b/c/d/that' );>> will create the
directory structure required as needed. 

In the file copy case, if the target already exists, and is a writable file,
we replace the existing file, retaining file mode and owners. If the target
is a directory, we do NOT copy into that directory, unlike with the 'cp'
unix command. And error is instead returned.

C<copy> will also do limited recursive copying or directories. If source
is a directory, and target does not exists, a recursive copy of source will
be made to target. If target already exists ( file or directory ), C<copy>
will returns with an error.

=head2 move $source, $target

The C<move> method follows the conventions of the 'mv' command, with the 
exception that the directories containing target will of course be created
on demand.

=head2 remove $filename [, $prune ]

The C<remove> method will remove a file, or recursively remove a directory.

If a second (true) argument is provided, then once the file or directory
has been deleted, the method will the automatically work its way upwards
pruning (deleting) empty and thus presumably useless directories.

Returns true if the deletion (and pruning if requested) was a success, or
C<undef> otherwise.

=head2 prune $filename

=for stopwords CVS

For a file that has already been delete, C<prune> will work upwards,
removing any empty directories it finds.

For anyone familiar with CVS, it is similar to the C<update -P> flag.

Returns true, or C<undef> on error.

=head2 truncate $filename [, $size ]

The C<truncate> method will truncate an existing file to a particular size.
A size of 0 ( zero ) is used if no size is provided. If the file does not
exists, it will be created, and set to 0. Attempting to truncate a 
directory will fail.

Returns true on success, or undef on error.

=head2 makeDirectory $directory [, mode ]

In the case where you do actually have to create a directory only, the
C<makeDirectory> method can be used to create a directory or any depth.

An optional file mode ( default 0755 ) can be provided.

Returns true on success, returns undef on error.

=head1 TO DO

Function interface to be written, like
L<File::Spec::Functions>, to provide importable functions.

There's something bigger here too, I'm not exactly sure what it is,
but I think there might be the beginnings of a unified filesystem
interface here... FSI.pm

=head1 SEE ALSO

L<File::Spec>, L<http://ali.as/>

=head1 SUPPORT

Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=File-Flat>
(or L<bug-File-Flat@rt.cpan.org|mailto:bug-File-Flat@rt.cpan.org>).

=head1 AUTHOR

Adam Kennedy <adamk@cpan.org>

=head1 CONTRIBUTORS

=for stopwords Adam Kennedy Karen Etheridge

=over 4

=item *

Adam Kennedy <adam@ali.as>

=item *

Karen Etheridge <ether@cpan.org>

=back

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2002 by Adam Kennedy.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut