The Linux operating system pursues the concept that everything is a file. Almost all file devices can be operated with a set of system calls, namely open()/close()/write()/read(), etc. System calls are similar to C library calls in operating files. The man manual that comes with Linux is the most authoritative. Check the system call usage by checking the man manual.
Code name—— Meaning
open()——Open or create a file
Return Value type:
int——File descriptor fd. Every time a file is opened, a file descriptor will be obtained. This file descriptor is an integer. We perform read and write operations through the file descriptor.Failure: -1
Note:
These are actually defined macros. When multiple parameters need to be used, use bitwise or " |” to form multiple flag parameters can also be used together with the following method:
##Others will not be introduced one by one, please check yourself when you need to use them.
write()
Return value:
If successful, it has been written The number of bytes entered;
If an error occurs, it is -1;
Note: The number of bytes planned to be written and the return value of the function When not equal, it means there is an error in writing, which can be used to check whether the writing is successful;
fd
For ordinary files, write The operation starts from the current offset of the file. If the O_APPEND option is specified when opening the file, the file offset is set to the current end of the file before each write operation. After a successful write, the file offset is increased by the number of bytes actually written. read()
Return value: Number of bytes read
If the end of the file has been reached, it is 0; if there is an error, it is -1;
fd
. Before successfully returning, the displacement is increased by the number of bytes actually read (this displacement can be set by yourself); close()
Note: When a process terminates, all files it opens are automatically closed by the kernel.
Note: These functions without caching are system calls provided by the kernel; this is exactly the same as the IO we learned in C language Operations differ in that they are not part of standard C, but are part of POSIX.
When standard C operates on files, it operates on the structure pointer of FILE, and the file descriptor is used here.
The range of file descriptors is 0-OPEN MAX. The upper limit adopted by early Unix was 19 (that is, each process is allowed to open 20 files). Now many systems will soon increase to 63. Linux is 1024, the specific number can be found in the header file of
##File descriptor and file pointer
Function: Locate an open file
off_t lseek(int fd,off_t offset,int whence);
fd : File descriptor that has been opened;
offset: Displacement amount;
whence : Positioning position, that is, the reference point
SEEK_SET: Set the displacement of the file to offset bytes from the beginning of the file;
SEEK_CUR: Set the displacement of the file to its current value plus offset. The offset can be positive or negative;
SEEK_END: Set the displacement of the file to the file length plus offset. The offset can be positive or negative (if it is a positive value at this time, it involves a hole file, please see the explanation below);
Hole file example:
#include<stdio.h> #include<fcntl.h> #include<string.h> #include<stdlib.h> #include<unistd.h> #include<errno.h> //生成空洞文件 char *buffer = "0123456789"; int main(int argc,char *argv[]) { if(argc < 2) { fprintf(stderr,"-usage:%s [file]\n",argv[0]); exit(1); } int fd = open(argv[1],O_WRONLY | O_CREATE | O_TRUNC,0777); if(fd < 0) { perror("open error"); exit(1); } size_t size = strlen(buffer) * sizeof(char); //将字符串写入到空洞文件中 if(write(fd,buffer,size) != size) { perror("write error"); exit(1); } //定位到文件尾部的10个字节处 if(lseek(fd,10L;SEERK_END) < 0) { perror("lseek error"); exit(1); } //从文件尾部的10个字节处再写入字符串 if(write(fd,buffer,size) != size) { perror("write error"); exit(1); } close(fd); return 0; }
Example:
The running results are as follows: fd = 3 The reason is: There is afile table on the internal PCB of the system , the file descriptor opened by recording is actually the subscript of the file table
The running results are as follows:
Application: Copy files using reading and writing
To complete the copy of an image, we can use the following solution:
Open a new file
Read part of the original binary file and write it to the new file
Read and write repeatedly
Until reading is finished, stop after writing [read() == 0 is used as the condition for loop stop, if it cannot be read, it is finished]
Copying completed
Copying completed
Every time we open a file, a structure such as struct file will be generated in the kernel to represent the open file and record the following information:
File offset (starts from 0, the file pointer offsets as data is written)
Reference count (several processes are using this Open file)
inode node (stores the attribute information of the process: who created it, what is the name, and where is it stored on the disk. Through this inode node, we can find the corresponding specific file)
Opening method: For example, read-only mode, write-only mode open
Test 1: Open the file first and then fork
close (fd) is written on the outermost side, and both the parent and child processes will be closed. Each time they are closed, the reference count will be decremented by 1 until it reaches 0.
The running results are as follows:
The reasons are as follows:
Test 2: First fork and then open the file
After modifying the code, the running results change as follows:
Because the parent and child processes opened their own files after they were separated, Their own struct files are generated, and file offsets are no longer shared.
In actual application scenarios, we mostly use files opened by the parent process and child processes to access this form.
The above is the detailed content of How to call the underlying system of Linux operating files. For more information, please follow other related articles on the PHP Chinese website!