_learning perl_, ch10, 5.I.2002, nh FILEHANDLES def: a FILEHANDLE is the name for an I/O connection between your Perl === process and the outside world. STDIN STDOUT STDERR | `-> like names for labeled blocks, but they come from yet another namespace (so you can have $x, @x, %x, &x (sub), X (label), and X filehandle!) | `-> all uppercase letters opening and closing filehandles: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ open (FILEHANDLE,"filename"); # opens filename for reading open (OUT, ">outfile"); # prefixing with '>' opens it for writing open (LOGFILE, ">>logname"); # two '>>'s opens it for appending | `-> all forms return "true" for success & "false" for failure close (FILEHANDLE); # closes file with that filehandle # (but closing the program closes # that file automatically) die: checks result of 'open' and reports an error === unless (open FILEHANLDE,"filename") { die "Sorry, couldn't open filename." } # rest of program or just, (open FILEHANLDE,"filename") || # => "open that file die "Sorry, couldn't open filename."; # or die!" if you don't want the line # shown, put a \n in the msg. $! = contains the error string descrbing most recent operating system error open (FILEHANDLE,"filename") || die ("$!"); also, warn: ==== open (FILEHANDLE,"filename") || warn ("discarding file"); doesn't die, but does everything short of it. using filehandles: ~~~~~~~~~~~~~~~~~ open("PASSWD,"/etc/passwd"); while() { # functions like reading print "i saw $_ in /etc/passwd!\n"; # from <>, or } printing to file: ================ place filehandle right after print statement: print LOGFILE ("Just did $this at " . `date` . "\n"); print STDOUT "hello, world!"; # STDOUT is default filehandle for print statement the -x file tests: ~~~~~~~~~~~~~~~~~ x() if (-e $filename); # x is done if $filename exists x() if (-r $filename && -w $filename) # if it's read- & writeable filetest | meaning ---------|-------- -e | file or directory exists -r | file or directory is readable -w | file or directory is writeable -x | file or directory is executable -o | file or directory is owned by user -R | file or directory is readable by *real* user -W | file or directory is writable by *real* user -O | file or directory is owned by *real* user -z | file exists and has zero size -s | file exists and has nonzero size (returns number of | bytes as value, which, if nonzero, *is* true ...) -f | entry is a plain file -d | entry is a directory -l | entry is a symlink -S | entry is a socket -p | entry is a named pipe (a "fifo") -b | entry is a block-special file (like a mountable disk) -c | entry is a character-special file (like an I/O device) -u | file or directory is setuid -g | file or directory is setgid -k | file or directory has the sticky bit set -t | isatty() on the filehandle is true -T | file is "text" -B | file is "binary" -M | modification age in days | be careful -- theses -A | access age in days > return precise values! -C | inode-modification age in days | (don't compare to '3'; they will only return files modified | EXACTLY 3 days ago) `-> can use on FILEHANDLES as well as filenames | `-> if you leave the filehandle/name off, default is $_ stat and lstat: ~~~~~~~~~~~~~~ 'stat' returns everything you want to know about a file: ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, $blksize,$blocks) = stat(...) 0 mode_t st_mode; # File mode 1 ino_t st_ino; # Inode number 2 dev_t st_dev; # ID of device containing a directory entry for this file 3 dev_t st_rdev; # ID of device -- This entry is defined only for char special, block special, and lofs files 4 nlink_t st_nlink; # Number of links 5 uid_t st_uid; # User ID of the file's owner 6 gid_t st_gid; # Group ID of the file's group 7 off_t st_size; # File size in bytes 8 timespec_t st_atim; # Time of last access 9 timespec_t st_mtim; # Time of last data modification 10 timespec_t st_ctim; # Time of last file status change -- Times measured in seconds and nanoseconds -- since 00:00:00 UTC, Jan. 1, 1970 11 long st_blksize; # Preferred I/O block size 12 blkcnt_t st_blocks; # Number 512 byte blocks allocated * 'lstat' works like stat on things that aren't symbolic links.