A
When we open a file, the general operation of the file is read-write. The read and write functions are read and write respectively.
#include <unistd.h>
ssize_t Read (int fd, void *buf, size_t count);
Parameters:
FD: A file descriptor obtained using open, creat.
Buf:buf is a void * type, used to represent a generic pointer, where the memory buffer of the data being read is referred to.
Count: The amount of data that needs to be read.
Return value: When executed successfully, returns the number of bytes of data read, typically equal to or less than the number of bytes of data requested to read. Returns 0 if it has reached the end of the file, or 1 if an error occurs. When the failure returns 1, error is set to one of the following values. This error is usually set in the kernel driver, not the application settings.
Eagain: The O_NONBLOCK flag is set when the file is opened and there is currently no data to read
EBADF: File descriptor is invalid or the file is unreadable
Efault: The space that the parameter buf points to is inaccessible
EINTR: The operation is interrupted by signal before the data is read
EINVAL: One or more parameters are invalid
EIO: Read and write errors
Eisdir: The time table of the parameter FD index
The above mentioned return value may be less than the number of bytes requested to read. The reasons may be:
1. When you read a normal file, you have reached the end of the file before you read the required number of bytes.
2, when reading from the terminal device, usually read a line at most once.
3. When reading from the network, the buffer mechanism in the network may cause the return value to be less than the number of bytes required to read.
4, when reading from a pipe or FIFO, if the pipe contains fewer bytes than required, then read will only return the actual number of bytes available.
5. When reading from some record-oriented devices, a maximum of one record is returned at a time.
6, when a signal caused by interruption, and have read some of the data. (The situation will be discussed in detail later in the signal section)
Two
#include <unistd.h>
ssize_t Write (int fd, const void *buf, size_t count);
The Write function, in contrast to the Read function, writes data to an open file.
Parameters:
FD: A file descriptor obtained using open, creat.
Buf:buf is a void * type, used to represent a generic pointer, where the memory buffer of the data being written is referred to.
Count: The amount of data that needs to be written.
Return value: Returns the number of bytes written if successful, or 1 if an error occurs.
Note: For normal files, write operations from the file's at current offset start. If the O_append option is specified when the file is opened, the file offset is set at the current end of the file before each write operation. After a successful write, the file offset increases the number of bytes actually written.
Three
The note section of the Write function above has a description of "at the current offset of the file," What if I want to write data from the beginning of the file or at the end of the file? This is the use of another I/O function Lseek function.
In fact, each open file has a "current file offset" associated with it. It is usually a non-negative integer that measures the number of bytes computed from the beginning of the file. Typically, read and write operations start at the current file offset and increase the number of bytes read and written by the offset. By default, when you open a file, the offset is set to 0 unless you specify the O_append option.
#include <sys/types.h>
#include <unistd.h>
off_t lseek (int fd, off_t offset, int whence);
Parameters:
Filedes: use Open, creat to get the file descriptor.
Offset and whence, whence has three seek_set, Seek_cur, Seek_end.
1, if whence is seek_set, the offset of the file is set to offset bytes from the beginning of the file.
2, if whence is seek_cur, the offset of the file is set to its current value plus offset,offset can be negative.
3, if whence is seek_end, the file offset is set to the file length plus offset,offset can be negative.
Return value: Returns the new file offset if successful, or 1 if an error occurs.
Attention:
1, not all files can set the file offset, for pipelines, FIFO, network sockets, etc. cannot set the file offset. the following methods can be used to judge:
off_t currpos;currpos = Lseek (FD, 0, seek_cur); If the return value is-1, you cannot set the file offset and set the error to espipe.
2, because the offset may be negative, you should be careful when comparing the return value of Lseek, do not test whether it is less than 0, and test whether it is equal to-1.
if (Lseek (Stdin_fileno, 0, seek_cur) = =-1)
3. Lseek only records the file offset in the kernel, and it does not cause any I/O operations. The offset is then used for the next read and write operation. The file offset can be larger than the current length of the file and can form an empty hole in the file, and the holes in the file do not require the storage to be occupied on disk.
(iv)
/* *file name:demo.c *author : libing *mail : [email protected] *function:read, write, Lseek */#include < stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h># Include <sys/stat.h> #define Buffsize 2048intmain (void) {int Fd;char buf[buffsize] = {0, 1, 2, 3};ssize_t nbytes;
//Create a new file TEST.TXTFD = open ("Test.txt", O_RDWR | O_creat, S_IRUSR | S_IWUSR); if (fd = =-1) {printf ("creat test.txt failed.\n"); exit (1);} Write data to file Nbytes = Write (fd, buf, buffsize); if (nbytes = =-1) {printf ("read failed.\n");} Set the offset for the open file to the beginning of the file if (Lseek (FD, 0, seek_set) = =-1) {printf ("Cannot seek\n");} Read file Data nbytes = Read (FD, buf, buffsize), if (nbytes = =-1) {printf ("read failed.\n");} printf ("nbytes =%d.\n", nbytes); return 0;}
compile test results:
Compiler: GCC demo.c run the program:./a.out the results show: Nbytes = 2048.
(v)
Application Examples:
Linux, we often use the CP command to copy a file content to another file, such as CP file1 file2. Copy of the command, we can use the file I/O to complete .
/* *file name:copy.c *author:libing *mail: [email protected] *Function : Copy file1 to File2 */#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h& gt; #include <sys/types.h> #include <sys/stat.h>intmain (int argc, char *argv[]) {int file1fd;int file2fd; Char buf[2048];int nbytes;if (argc! = 3) {printf ("Usage%s file1 file2.\n", argv[0]); return 0;} source file, which is the file to be copied FILE1FILE1FD = Open (argv[1], o_rdonly), if (file1fd = =-1) {printf ("Open file1 failed.\n"); return 0;} Destination file, which is the file to be copied to FILE2FILE2FD = open (argv[2], o_wronly | O_creat | O_trunc, S_IRUSR | S_IWUSR); if (file2fd = =-1) {printf ("Open file2 failed.\n"); return 0;} Copying files while ((nbytes = Read (FILE1FD, buf, 2048)) > 0) write (FILE2FD, buf, Nbytes); close (FILE1FD); close (FILE2FD); return 0;}
Compile the result test compile file: gcc copy.c execution file:./a.out demo.c test.txt Display results: VI test.txt can see the same content as demo.c content.