← Perl EnglishChapter 09 of 13

File I/O

## Learning Objectives - Open and close filehandles - Read from files - Write to files - Use directory operations - Work with file tests - Handle binary data ## Filehandles ### Opening Files ```perl use strict; use warnings; # Read from file open my $fh, "<", "input.txt" or die "Cannot open: $!"; # Write to file (overwrite) open my $fh, ">", "output.txt" or die "Cannot open: $!"; # Append to file open my $fh, ">>", "log.txt" or die "Cannot open: $!"; # Read/Write (read + write, truncate) open my $fh, "+>", "temp.txt" or die "Cannot open: $!"; # Read/Write (read + write, no truncate) open my $fh, "+<", "temp.txt" or die "Cannot open: $!"; ``` ### Three-Argument Open ```perl # Modern way (recommended) open my $fh, "<", "filename.txt" or die "Cannot open: $!"; # With encoding open my $fh, "<:encoding(UTF-8)", "file.txt" or die "Cannot open: $!"; # Raw binary open my $fh, "<:raw", "binary.dat" or die "Cannot open: $!"; ``` ### Closing Files ```perl close $fh or die "Cannot close: $!"; ``` ## Reading from Files ### Line-by-Line Reading ```perl use strict; use warnings; open my $fh, "<", "input.txt" or die "Cannot open: $!"; while (my $line = <$fh>) { chomp $line; print "Read: $line\n"; } close $fh; ``` ### Reading into Array ```perl open my $fh, "<", "input.txt" or die "Cannot open: $!"; my @lines = <$fh>; close $fh; # More efficient - slurp entire file open my $fh, "<", "input.txt" or die "Cannot open: $!"; my $content = do { local $/; <$fh> }; # Slurp mode close $fh; ``` ### Read All Lines ```perl # Using File::Slurp (CPAN module) use File::Slurp qw(read_file write_file); my @lines = read_file("file.txt"); my $content = read_file("file.txt"); ``` ## Writing to Files ### Print to Filehandle ```perl use strict; use warnings; open my $fh, ">", "output.txt" or die "Cannot open: $!"; print $fh "Hello, World!\n"; print $fh "Line 2\n"; close $fh; ``` ### printf to File ```perl open my $fh, ">", "data.txt" or die "Cannot open: $!"; printf $fh "Name: %-10s Age: %3d\n", "Alice", 30; printf $fh "Name: %-10s Age: %3d\n", "Bob", 25; close $fh; ``` ### write (Formatted) ```perl use strict; use warnings; format STUDENT = @<<<<<<<<<<< @>> @####.## Name: Age: GPA ~~ ~~ ~~~~~ . # Write using format open my $fh, ">", "students.txt" or die "Cannot open: $!"; select $fh; write; select STDOUT; close $fh; ``` ## Standard Filehandles ### STDIN, STDOUT, STDERR ```perl use strict; use warnings; # Read from STDIN print "Enter your name: "; my $name = ; chomp $name; # Print to STDOUT print STDOUT "Hello, $name!\n"; # Print to STDERR print STDERR "Error message\n"; ``` ### Redirecting Output ```perl # Redirect STDERR to STDOUT print STDERR "Error\n"; # Goes to stderr # Combined open my $log, ">>", "log.txt" or die "Cannot open: $!"; print $log "Message\n"; # Appends to log close $log; ``` ## File Tests ### Test Operators ```perl use strict; use warnings; use -e File::Spec; my $file = "test.txt"; -e $file; # Exists? -r $file; # Readable? -w $file; # Writable? -x $file; # Executable? -f $file; # Regular file? -d $file; # Directory? -l $file; # Symbolic link? -s $file; # Size in bytes (returns size or undef) -z $file; # Empty file? -T $file; # Text file? -B $file; # Binary file? ``` ### File Test Examples ```perl use strict; use warnings; my $file = "data.txt"; if (-e $file) { print "File exists\n"; if (-r $file && -w $file) { print "File is readable and writable\n"; } if (-s $file > 1024) { print "File is larger than 1KB\n"; } } else { print "File does not exist\n"; } ``` ### Stacked Tests ```perl my $file = "test.txt"; if (-r -w -x $file) { print "Full permissions\n"; } if (-o $file) { # Owned by current user print "You own this file\n"; } ``` ## Directory Operations ### Reading Directories ```perl use strict; use warnings; opendir my $dh, "." or die "Cannot open dir: $!"; while (my $entry = readdir $dh) { next if $entry =~ /^\./; # Skip hidden files print "$entry\n"; } closedir $dh; ``` ### Globbing ```perl use strict; use warnings; # All files matching pattern my @pl_files = glob "*.pl"; my @pl_files = <*.pl>; # All files recursively (Perl 5.10+) use File::Glob qw(bsd_glob); my @all = bsd_glob("**/*", GLOB_NOCHECK); ``` ### Making Directories ```perl use strict; use warnings; mkdir "newdir", 0755 or die "Cannot create: $!"; # Recursive mkdir use File::Path qw(make_path); make_path("path/to/deep/dir"); # Remove directory (must be empty) rmdir "emptydir" or die "Cannot remove: $!"; ``` ### Removing Files ```perl use strict; use warnings; unlink "file_to_delete.txt" or die "Cannot delete: $!"; # Remove multiple unlink "a.txt", "b.txt", "c.txt"; # Remove with check unlink "old.txt" if -e "old.txt"; ``` ## Path Manipulation ### File::Spec ```perl use strict; use warnings; use File::Spec; my $path = File::Spec->catfile("dir", "subdir", "file.txt"); # Cross-platform path building my $full = File::Spec->catpath("C:", "Users", "test.txt"); ``` ### Path::Tiny (CPAN) ```perl use Path::Tiny; my $path = path("dir/file.txt"); $path->slurp; # Read content $path->spew("content"); # Write content $path->exists; $path->is_file; $path->is_dir; $path->parent; # Parent directory $path->child("sub"); # Child path ``` ## Working with File Paths ### Extracting Components ```perl use strict; use warnings; use File::Basename; my $path = "/home/user/docs/file.txt"; my $filename = fileparse($path); # "file.txt" my $dirname = dirname($path); # "/home/user/docs" my $extension = fileparse($path, qr/\.[^.]*/); # ".txt" ``` ### Path Information ```perl use File::Basename; my $path = "/home/user/docs/file.txt"; my ($name, $dir, $ext) = fileparse($path, qr/\.[^.]*/); print "Name: $name, Dir: $dir, Ext: $ext\n"; ``` ## Binary Data ### Reading Binary ```perl use strict; use warnings; open my $fh, "<:raw", "image.png" or die "Cannot open: $!"; binmode $fh; # Important on Windows my $data; { local $/; # Slurp mode $data = <$fh>; } close $fh; print length($data), " bytes\n"; ``` ### Writing Binary ```perl use strict; use warnings; open my $fh, ">:raw", "output.bin" or die "Cannot open: $!"; binmode $fh; print $fh $binary_data; close $fh; ``` ## Temporary Files ### Named Temporary Files ```perl use strict; use warnings; use File::Temp qw(tempfile); my ($fh, $filename) = tempfile( "prefixXXXXX", # Template with X's for random chars DIR => "/tmp", SUFFIX => ".txt", ); print $fh "Temporary content\n"; close $fh; unlink $filename if -e $filename; ``` ### Anonymous Temporary File ```perl use File::Temp qw(tempfile); my ($fh, $filename) = tempfile(); print $fh "Temp content\n"; close $fh; unlink $filename; ``` ## Error Handling ### Checking Open Success ```perl use strict; use warnings; open my $fh, "<", "nonexistent.txt" or die "Cannot open file: $!"; # Or with or open(my $fh, "<", "file.txt") || die "Cannot open: $!"; # Custom error open my $fh, "<", "file.txt" or die "Cannot open 'file.txt': $!"; ``` ### $! Variable ```perl open my $fh, "<", "file.txt" or do { warn "Error: $!"; return; }; ``` ## Summary - Use `open` with three arguments for safety - `<$fh>` reads one line, `<$fh>` in list context reads all - `print $fh` writes to file - `close $fh` when done - File tests: `-e`, `-r`, `-w`, `-f`, `-d`, `-s` - `opendir`/`readdir` for directories - `glob` or `` for file globbing - `mkdir`/`rmdir` for directory operations - `unlink` to delete files - Use `binmode` for binary data - File::Temp for temporary files

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →