Perl uses a type of variable called a file handle to operate on files.
\\n\\nReading from or writing to a file requires the use of a file handle.
\\n\\nFile handle is the name of an I/O connection.
\\n\\nPerl provides three file handles: STDIN, STDOUT, and STDERR, representing standard input, standard output, and standard error output, respectively.
\\n\\nIn Perl, you can open a file using the following methods:
\\n\\nopen FILEHANDLE, EXPR\\nopen FILEHANDLE\\nsysopen FILEHANDLE, FILENAME, MODE, PERMS\\nsysopen FILEHANDLE, FILENAME, MODE\\n\\n\\nParameter description:
\\n\\n- \\n
- FILEHANDLE: The file handle, used to store a unique identifier for a file. \\n
- EXPR: An expression consisting of the filename and the file access mode. \\n
- MODE: The file access mode. \\n
- PERMS: Permission bits. \\n
\\n\\n
open Function
\\n\\nThe following code uses the open function to open the file file.txt in read-only mode (<):
open(DATA, "<file.txt");\\n\\n\\n< indicates read-only mode.
In the code, DATA is the file handle used to read the file. The following example will open the file and output its contents:
Example
\\n\\n#!/usr/bin/perl\\n\\nopen(DATA, "<file.txt") or die "file.txt file cannot open, $!";\\nwhile(<DATA>){\\n print "$_";\\n}\\n\\n\\nThe following code opens the file file.txt in write mode (>):
open(DATA, ">file.txt") or die "file.txt file cannot open, $!";\\n\\n\\n> indicates write mode.
If you need to open a file for both reading and writing, you can add a + sign before the > or < character:
open(DATA, "+<file.txt") or die "file.txt file cannot open, $!";\\n\\n\\nThis method will not delete the original content of the file. To delete it, use the following format:
\\n\\nopen DATA, "+>file.txt" or die "file.txt file cannot open, $!";\\n\\n\\nTo append data to a file, you only need to open the file in append mode before appending:
\\n\\nopen(DATA, ">>file.txt") || die "file.txt file cannot open, $!";\\n\\n\\n>> indicates appending data to the end of an existing file. If you need to read the contents of the file to be appended, you can add a + sign:
open(DATA, "+>>file.txt") || die "file.txt file cannot open, $!";\\n\\n\\nThe following table lists the different access modes:
\\n\\n| Mode | \\nDescription | \\n
|---|---|
< or r | \\nOpen for reading only, with the file pointer positioned at the beginning of the file. | \\n
> or w | \\nOpen for writing only, with the file pointer positioned at the beginning of the file and the file size truncated to zero. If the file does not exist, it attempts to create it. | \\n
>> or a | \\nOpen for writing only, with the file pointer positioned at the end of the file. If the file does not exist, it attempts to create it. | \\n
+< or r+ | \\nOpen for reading and writing, with the file pointer positioned at the beginning of the file. | \\n
+> or w+ | \\nOpen for reading and writing, with the file pointer positioned at the beginning of the file and the file size truncated to zero. If the file does not exist, it attempts to create it. | \\n
+>> or a+ | \\nOpen for reading and writing, with the file pointer positioned at the end of the file. If the file does not exist, it attempts to create it. | \\n
\\n\\n
Sysopen Function
\\n\\nThe sysopen function is similar to the open function, but their parameter formats are different.
\\n\\nThe following example opens a file for reading and writing (+<filename):
sysopen(DATA, "file.txt", O_RDWR);\\n\\n\\nIf you need to clear the file before updating it, the syntax is as follows:
\\n\\nsysopen(DATA, "file.txt", O_RDWR|O_TRUNC);\\n\\n\\nYou can use O_CREAT to create a new file, O_WRONLY for write-only mode, and O_RDONLY for read-only mode.
The PERMS parameter is an octal attribute value representing the permissions of the file after creation, with a default of 0x666.
\\n\\nThe following table lists possible mode values:
\\n\\n| Mode | \\nDescription | \\n
|---|---|
O_RDWR | \\nOpen for reading and writing, with the file pointer positioned at the beginning of the file. | \\n
O_RDONLY | \\nOpen for reading only, with the file pointer positioned at the beginning of the file. | \\n
O_WRONLY | \\nOpen for writing only, with the file pointer positioned at the beginning of the file and the file size truncated to zero. If the file does not exist, it attempts to create it. | \\n
O_CREAT | \\nCreate a file. | \\n
O_APPEND | \\nAppend to the file. | \\n
O_TRUNC | \\nTruncate the file size to zero. | \\n
O_EXCL | \\nIf the file exists when using O_CREAT, it returns an error message. It can be used to test if a file exists. | \\n
O_NONBLOCK | \\nNon-blocking I/O ensures that our operation either succeeds or immediately returns an error without being blocked. | \\n
\\n\\n
Close Function
\\n\\nAfter using a file, you should close it to flush the input/output buffers associated with the file handle. The syntax for closing a file is as follows:
\\n\\nclose FILEHANDLE\\nclose\\n\\n\\nFILEHANDLE is the specified file handle. If closed successfully, it returns true.
close(DATA) || die "cannot close file";\\n\\n\\n\\n\\n
Reading and Writing Files
\\n\\nThere are several different ways to read and write information to a file:
\\n\\n<FILEHANDLE> Operator
\\n\\nThe main method for reading information from an open file handle is the <FILEHANDLE> operator. In a scalar context, it returns a single line from the file handle. For example:
Example
\\n\\n#!/usr/bin/perl\\n\\nprint "URL?n";\\n$name = <STDIN>;\\nprint "URL:$namen";\\n\\n\\nAfter executing the above program, it will display the following information. After we enter the URL, the print statement will output:
\\n\\nWhen we use the <FILEHANDLE> operator, it returns a list of each line in the file handle. For example, we can import all lines into an array.
First, create an import.txt file with the following content:
$ cat import.txt\\n123\\n\\n\\nRead import.txt and put each line into the @lines array:
Example
\\n\\n#!/usr/bin/perl\\n\\nopen(DATA, "<import.txt") or die "cannot open data";\\n@lines = <DATA>;\\nprint @lines;\\nclose(DATA);\\n\\n\\nAfter executing the above program, the output is:
\\n\\n123\\n\\n\\ngetc Function
\\n\\nThe getc function returns a single character from the specified FILEHANDLE. If not specified, it returns from STDIN:
getc FILEHANDLE\\ngetc\\n\\n\\nIf an error occurs, or if the file handle is at the end of the file, it returns undef.
\\n\\n
read Function
\\n\\nThe read function is used to read information from a buffered file handle.
This function is used to read binary data from a file.
\\n\\nread FILEHANDLE, SCALAR, LENGTH, OFFSET\\nread FILEHANDLE, SCALAR, LENGTH\\n\\n\\nParameter description:
\\n\\n- \\n
- FILEHANDLE: The file handle, used to store a unique identifier for a file. \\n
- SCALAR: Stores the result. If OFFSET is not specified, the data will be placed at the beginning of SCALAR. Otherwise, the data is placed OFFSET bytes into SCALAR. \\n
- LENGTH: The length of the content to read. \\n
- OFFSET: The offset. \\n
If the read is successful, it returns the number of bytes read. If at the end of the file, it returns 0. If an error occurs, it returns undef.
print Function
\\n\\nFor all functions that read information from a file handle, the main write function at the backend is print:
print FILEHANDLE LIST\\nprint LIST\\nprint\\n\\n\\nUsing a file handle and the print function, you can send the results of program execution to an output device (STDOUT: standard output). For example:
print "Hello World!n";\\n\\n\\nFile Copy
\\n\\nIn the following example, we will open an existing file file1.txt, read each line, and write it to the file file2.txt:
Example
\\n\\n#!/usr/bin/perl\\n\\nopen(DATA1, "<file1.txt");\\nopen(DATA2, ">file2.txt");\\n\\nwhile(<DATA1>){\\n print DATA2 $_;\\n}\\n\\nclose(DATA1);\\nclose(DATA2);\\n\\n\\nFile Rename
\\n\\nIn the following example, we rename the existing file file1.txt to file2.txt. The specified directory is /usr/tutorial/test/:
#!/usr/bin/perl\\n\\nrename ("/usr/tutorial/test/file1.txt", "/usr/tutorial/test/file2.txt" );\\n\\n\\nThe rename function only accepts two parameters and only renames existing files.
\\n\\nDelete File
\\n\\nThe following example demonstrates how to use the unlink function to delete a file:
\\n\\nExample
\\n\\n#!/usr/bin/perl\\n\\nunlink("/usr/tutorial/test/file1.txt");\\n\\n\\n\\n\\n
Specifying File Position
\\n\\nYou can use the tell function to get the current position of the file, and the seek function to specify a position within the file:
\\n\\ntell Function
\\n\\nThe tell function is used to get the file position:
tell FILEHANDLE\\ntell\\n\\n\\nIf FILEHANDLE is specified, this function returns the position of the file pointer in bytes. If not specified, it returns the position of the default selected file handle.
seek Function
\\n\\nThe seek() function reads or writes a file by moving the file read/write pointer via the file handle, reading and writing in bytes:
seek FILEHANDLE, POSITION, WHENCE\\n\\n\\nParameter description:
\\n\\n- \\n
- FILEHANDLE: The file handle, used to store a unique identifier for a file. \\n
- POSITION: The number of bytes the file handle (read/write position pointer) is to move. \\n
- WHENCE: The starting position from which the file handle (read/write position pointer) begins to move. The possible values are 0, 1, and 2, representing the beginning of the file, the current position, and the end of the file, respectively. \\n
The following example reads 256 bytes from the beginning of the file:
\\n\\nseek DATA, 256, 0;\\n\\n\\n\\n\\n
File Information
\\n\\nPerl's file operations can also test whether a file exists, is readable or writable, etc.
\\n\\nWe can first create a file1.txt file with the following content:
$ cat file1.txt\\nwww.\\n\\n\\nExample
\\n\\nmy $file = "/usr/test/tutorial/file1.txt";\\nmy(@description, $size);\\n\\nif (-e $file) {\\n push @description, 'is a binary file' if (-B _);\\n push @description, 'is a socket(socket)' if (-S _);\\n push @description, 'is a text file' if (-T _);\\n push @description, 'is a special block file' if (-b _);\\n push @description, 'is a special character file' if (-c _);\\n push @description, 'is a directory' if (-d _);\\n push @description, 'file exists' if (-x _);\\n push @description, (($size = -s _)) ? "$size bytes" : 'Empty';\\n print "$file info:", join(', ', @description), "n";\\n}\\n\\n\\nAfter executing the above program, the output is:
\\n\\nfile1.txt Info: is a text file, 15 bytes\\n\\n\\nThe file test operators are listed in the following table:
\\n\\n| Operator | \\nDescription | \\n
|---|---|
-A | \\nTime since last access (in days) | \\n
-B | \\nIs it a binary file? | \\n
-C | \\nInode modification time (in days) | \\n
-M | \\nTime since last modification (in days) | \\n
-O | \\nFile is owned by real UID | \\n
-R | \\nFile or directory is readable by real UID/GID | \\n
-S | \\nIs it a socket? | \\n
-T | \\nIs it a text file? | \\n
-W | \\nFile or directory is writable by real UID/GID | \\n
-X | \\nFile or directory is executable by real UID/GID | \\n
-b | \\nIs it a block-special file (e.g., mounted disk)? | \\n
-c | \\nIs it a character-special file (e.g., I/O device)? | \\n
-d | \\nIs it a directory? | \\n
-e | \\nDoes the file or directory name exist? | \\n
-f | \\nIs it a regular file? | \\n
-g | \\nDoes the file or directory have the setgid attribute? | \\n
-k | \\nDoes the file or directory have the sticky bit set? | \\n
-l | \\nIs it a symbolic link? | \\n
-o | \\nFile is owned by effective UID | \\n
-p | \\nIs the file a named pipe (FIFO)? | \\n
-r | \\nFile is readable by effective UID/GID | \\n
-s | \\nFile or directory exists and is not zero (returns byte count) | \\n
-t | \\nIs the file handle a TTY (return value of system function isatty(); this test cannot be used on filenames)? | \\n
-u | \\nDoes the file or directory have the setuid attribute? | \\n
-w | \\nFile is writable by effective UID/GID | \\n
-x | \\nFile is executable by effective UID/GID | \\n
-z | \\nFile exists and size is zero (always false for directories), i.e., is it an empty file? | \\n
YouTip