Chapter 11 – File and Directory Manipulation Outline 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8
Introduction File Tests and sysopen Permissions File Manipulation Hard Links and Symbolic Links File Globbing Directory Handles and Manipulation Example: Web Site Recent-Update Page
2001 Prentice Hall, Inc. All rights reserved.
Test Meaning
Test
Meaning
-r
Is the file readable?
-w
Is the file writable?
-e
Does the file exist?
-z
File exists and has a size of zero.
-s
File exists and has a nonzero size. The size in bytes is returned.
-f
Is the file a plain file?
-d
File is directory.
-T
Is the file a text file?
-B
File is a binary file.
-M
Age from last time file was modified.
-A
Age from time file was last accessed.
-C
Age since file was created.
-x
Is the file executable?
Fig. 11.1 Some file tests.
2001 Prentice Hall, Inc. All rights reserved.
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
Outline
#!/usr/bin/perl # Fig. 11.2: fig11_02.pl # A program that uses file tests use strict; use warnings; foreach my $file ( @ARGV ) { print( "Checking $file: " ); if ( -e $file ) { # does file print( "$file exists!\n" );
The filename test -e determines whether a file exists. File test -f file test shows whether or not a file is a plain file. Calling a file “plain” exist? means that the file is not a special type of file or listing.
if ( -f $file ) { # is the file a plain file? print( "The file $file is:" ); print( " executable" ) if ( -x $file ); # executable? print( " readable" ) if ( -r $file ); # readable? print( " writable" ) if ( -w $file ); # writable? print( "\n" ); print( "It is ", -s $file, " bytes.\n" ); # size my @time = timeconv( -A $file ); # accessed print( "Last accessed at $time[0] days, ", "$time[1] hours, $time[2] minutes ", "and $time[3] seconds.\n" ); @time = timeconv( -M $file ); # modified print( "Last modified at $time[0] days, ", "$time[1] hours, $time[2] minutes, ", "and $time[3] seconds ago.\n" ); } 2001 Prentice Hall, Inc. All rights reserved.
File tests –x, -r and –w show whether the file is executable, readable and writable, respectively. File tests –M and -A return the number of days (or fraction thereof) since the If a file is nonempty, -s file was last modified or last returns the size of the file accessed, respectively. in bytes.
30
elsif ( -d $file ) {
31 }
33
}
34
else {
35
File test –d shows whether the file is directory.
print( "$file doesn't exist.\n" ); }
37 38
Outline
print( "$file is a directory!\n" );
32
36
# is it a directory?
print( "\n" );
39 } 40 41 sub timeconv 42 { 43
my $time = shift();
44
my $days = int( $time );
45
$time = ( $time - $days ) * 24;
46
my $hours = int( $time );
47
$time = ( $time - $hours ) * 60;
48
my $minutes = int( $time );
49
$time = ( $time - $minutes ) * 60;
50
my $seconds = int( $time );
51
return ( $days, $hours, $minutes, $seconds );
52 }
2001 Prentice Hall, Inc. All rights reserved.
Checking fig11_02.pl: fig11_02.pl exists! The file fig11_02.pl is: executable readable writable It is 1550 bytes. Last accessed at 0 days, 0 hours, 0 minutes and 0 seconds. Last modified at 0 days, 0 hours, 2 minutes, and 20 seconds ago.
Checking /home/pauldeitel: /home/pauldeitel exists! /home/pauldeitel is a directory!
Checking file.txt: file.txt exists! The file file.txt is: readable writable It is 51 bytes. Last accessed at 0 days, 2 hours, 40 minutes and 16 seconds. Last modified at 1 days, 17 hours, 39 minutes, and 28 seconds ago.
Checking fakefile.txt: fakefile.txt doesn't exist.
2001 Prentice Hall, Inc. All rights reserved.
Outline
Flag
Meaning
O_RDONLY
Open for reading only.
O_WRONLY
Open for writing only.
O_RDWR O_CREAT
Open for reading or writing. Create the file if it does not exist. Do not open the file if it already exists. Append to the end of the file.
O_EXCL O_APPEND O_TRUNC
Truncate the file’s existing contents. O_NONBLOCK Non-blocking access. Fig. 11.3 Flags for sysopen imported from Fcntl.
2001 Prentice Hall, Inc. All rights reserved.
Permission
Allows
0
The user(s) can do nothing.
1
The user(s) can execute.
2 3 4 5
The The The The
6 7
user(s) user(s) user(s) user(s)
can can can can
write. execute and write. read. read and execute.
The user(s) can read and write. The user(s) can read, write and execute. Fig. 11.4 Some of Perl’s file permissions.
2001 Prentice Hall, Inc. All rights reserved.
Outline
1
#!/usr/bin/perl
2
# Fig. 11.5: fig11_05.pl
3
# Renaming a file before accidental deletion
4 5
use warnings;
6
use strict;
Checks if the file exists.
7 8
if ( -e 'file.txt' ) {
9
print( "Do you want to write over file.txt? (yes or no): " );
10
chomp( my $response = <STDIN> );
11
rename( 'file.txt', 'file.old' )
12
or die( "Error renaming : $!" )
13
if ( $response eq 'no' );
14 }
If the user enters no, the contents of file.txt are copied to file.old.
15 16 open( FILE, ">file.txt" ) or die( "Error opening: $!" ); 17 print( FILE "A copy of file.txt is saved in file.old.\n" ); 18 close( FILE ) or die( "Cannot close: $!" ); Do you want to write over file.txt? (yes or no): no
The contents of file.txt are overwritten. 2001 Prentice Hall, Inc. All rights reserved.
file.txt before program executes: This is the original text from file.txt.
file.txt after program executes: A copy of file.txt is saved in file.old.
file.old after program executes: This is the original text from file.txt.
2001 Prentice Hall, Inc. All rights reserved.
Outline
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#!usr/bin/perl # Fig. 11.9: fig11_09.pl # Deleting a file with unlink
Outline Checks if the file is a plain file.
use strict; use warnings; print( "Input a file you want deleted: " ); chomp( my $file = <STDIN> );
Prompts the user for a file to be deleted.
if ( -f $file && unlink( $file ) ) { print( "The file was successfully deleted.\n" ); } else { Function unlink deletes print( "It was not deleted: $!" ); returns the number of }
Input a file you want deleted: file.old The file was successfully deleted. Input a file you want deleted: doesnotexist.txt It was not deleted: No such file or directory
2001 Prentice Hall, Inc. All rights reserved.
deleted.
a list of files and files successfully
Outline
1
#!perl
2
# Fig. 11.10: fig11_10.pl
3
# Website update-page creator.
4 5
use strict;
6
use warnings;
7
use CGI qw( :standard );
The program begins by declaring four variables with the keyword our, so that these values can be We declare $root to hold the value accessed by the user-defined "I:/Apache/cgi-bin/" and use functions that follow. chdir to change the working directory to this value.
8 9
our $indent = "|" . ( " " x 5 );
10 our $root = "I:/Apache/cgi-bin/"; 11 chdir( $root ); 12 our @colors = qw( red orange green ); 13 our @fileTypes = qw( html perl dir );
14 print( header(), start_html( -title => 'Update Page' ), 15
'' );
16 print( "$root:
\n" ); 17 search( "", 1 ); 18 print( "" );
Start the HTML page. Call to the function search. End the HTML page.
19 print( end_html() ); 20 21 sub search 22 { 23
my ( $directory, $offset ) = @_;
24
opendir( DIR, $root . $directory )
25
or die( "Error opening: $!" );
26
2001 Prentice Hall, Inc. All rights reserved.
Function opendirsearch is called to begins create Function by a directory handle for the current assigning the two arguments to directory to search. and $offset. In this $directory case, $directory is "", and $offset is 1.
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
foreach ( readdir( DIR ) ) { my $file = $directory . $_; printFile( 0, $file, $_, $offset ) if ( m/\.html/ ); printFile( 1, $file, $_, $offset ) if ( m/\.pl/ );
Outline
variable $file is assignedthen the IfThe theCalls current file is printFile a directory, Calls function function printFile if the if Thewant foreach structure directory in iterate which we iterates started we to through that file the isall anfile HTML afile Perl file. program file. through theis and directory ($directory) concatenated with directory as well using recursion. Recursive search. In this from call names incall thetocurrent directory. the current value returned toreaddir. search, we provide the new The directory name is printed directory name ($file) concatenated by calling with a path printFile. separator. Prints the $indent in a for structure based on $offset.
if ( -d $file && /[A-Za-z]/ ) { printFile( 2, $file, $_ . '/', $offset ); search( $file . '/', $offset + 1 ); print( "$indent" ) for ( 2 .. $offset ); print( br(), "\n" ); next; } } }
If the file was modified in the last sub printFile Function printFile by in the seven days (andbegins thus also { readinglast in 30 its arguments using the my ( $type, $file, $name, $offset ) = @_; days), bothand "brand " and my $full = $root . $file; Thefilename current color is also determined based with theare root directory "new!" printed aftertothe file. print( "$indent" ) for ( 2 .. $offset ); on assign the type offile file ormodified directory thethe full path name of $file If was in being thetolast print( "|----" ); printed. $full. 30 days, only the word "new!" is my $color = $colors[ $type ]; printed. my $extension = $fileTypes[ $type ]; print( "$extension: " ); The filename is printed. Sets the font color based on the print( "$_\n" ); previously set value $color print( em( strong( "brand " ) ) ) if ( -M $full < 7 ); print( strong( "new!" ), "\n" ) if ( -M $full < 30 ); and prints the type of file to be print( br(), "\n" ); printed. }
2001 Prentice Hall, Inc. All rights reserved.
Outline
2001 Prentice Hall, Inc. All rights reserved.