Virtual address space:
Linux does not run a program (process) operating system will allocate a 0~4G address space (virtual address space)
File descriptor: Disk files can be found through file descriptors
A process has a file descriptor table: 1024
The first three are occupied, occupied by standard input, standard output, and standard error
Use of the open function
Function prototype:
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
parameter:
flags
Required: O_RDONLY, O_WRONLY, O_RDWR
Options:
Create file: O_CREAT
Check whether the file exists when creating the file: O_EXCL
Returns -1 if the file exists
Must be used with O_CREAT
Append file: O_APPEND
File truncated: O_TRUNC
Set non-blocking: O_NONBLOCK
mode: is an octal number
code example
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>
int main()
{
//打开一个文件 hello
int fd = open("hello", O_RDWR|O_CREAT, 0777);//第一个是文件名,第二个参数是指定的操作,第三个参数是给定的权限
if(fd == -1)
{
printf("打开失败\n");
}
close(fd);//关闭文件描述符
return 0;
}
read_write function
read function: included in the header file <unistd.h>
Function prototype: ssize_t read(int fd, void *buf, size_t count);
parameter:
fd: open return value
buf: buffer
count: the maximum number of bytes that the buffer can store
return value:
-1: Indicates that the read failed
success:
>0: Indicates the number of bytes read
=0: means finished reading
b. write function: included in the header file <unistd.h>
Function prototype: ssize_t write(int fd, const void *buf, size_t count);
parameter:
fd: return value of open
buf: the data to write to the file
count: the effective number of bytes of buf
return value:
-1: Indicates that the write failed
>0: the number of bytes written to the file
Code example:
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<fcntl.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
{
int fd = open("text.txt", O_RDONLY);
if(fd == -1)
{
printf("打开失败\n");
}
int fd2 = open("text2.txt", O_WRONLY|O_CREAT, 0777);
char arr[20] = {0};
int len = read(fd, arr, 20);
while(len > 0)
{
int ret = write(fd2, arr, strlen(arr));
len = read(fd, arr, sizeof(arr));
}
close(fd2);
close(fd);
return 0;
}
perror function: included header file <errno.h>
Function prototype: void perror(const char *s);
Function: output error message
Parameter s: specifies the identity of the error message
lseek function: included in the header file <sys/types.h> <unistd.h>
Function prototype: off_t lseek(int fd, off_t offset, int whence);
Parameter whence option:
SEEK_SET
SEEK_CUR
SEEK_END
use:
The file pointer moves to the head
lseek(fd, 0, SEEK_SET);
Get the current position of the file pointer
int len = lseek(fd, 0, SEEk_CUR);
Get file length:
int lne = lseek(fd, 0, SEEK_END);
file extension
The original file size of 100k is expanded to 1000k
lseek(fd, 1000, SEEK_END);
last write operation
write(fd, "a", 1);
To achieve file extension, the above two steps must be performed
file extension code
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.h>
int main(int argc, const char* argv[])
{
int fd = open("english.txt", O_RDWR);
printf("fd = %d\n", fd);
if(fd == -1)
{
perror("open");
return -1;
}
//文件扩展
int len = lseek(fd, 1000, SEEK_END);//第二个参数表示文件指针移动的位数, 第三个参数表示从末尾开始移动
printf("len = %d\n", len);
write(fd, "a", 1);
close(fd);
return 0;
}
blocking and non-blocking
Depends on the properties of the file:
Ordinary files: the default is non-blocking
Terminal device: /dev/tty, blocked by default
stat and lstat functions: include header files <sys/types.h> <sys/stat.h> <unistd.h>
Function prototype: int stat(const char *pathname, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
The difference between the two functions:
lstat: read the attributes of the linked file itself
stat: What is read is the math of the file pointed to by the link file
Parameter pathname: file path
Parameter statbuf: is a stat structure object
stat structure:
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
blksize_t st_blksize; //块大小(文件系统的I/O缓冲区大小)
blkcnt_t st_blocks; //块数
struct timespec st_atim; //最后一次访问时间
struct timespec st_mtim; //最后一次修改时间
struct timespec st_ctim; //最后一次改变时间(指属性)
};
Get various attributes of the file:
The file uses hexadecimal numbers to represent all permissions:
0-2 bits: Indicates the authority of others
3-5 digits: Indicates the authority of the organization to which it belongs
6-8 digits: Indicates the permission of the file owner
12-15 digits: Indicates the permission of the file owner
Mask S_IFMT: 0170000 is an octal number, filtering information other than text in st_mode
Example: (st_mode & S_IFMT) == S_IFREG
Use code example:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
int main()
{
struct stat st;
int ret = stat("english.txt", &st);
if(ret == -1)
{
perror("stat error");
exit(1);
}
//输出文件大小
printf("file size = %d\n", (int)st.st_size);
//文件类型判断--判断是否是普通文件
if((st.st_mode & S_IFMT) == S_IFREG)//S_IFMT 是一个掩码,获取到的文件与上该掩码可以得到一个对应类型的二进制数
{
printf("该文件是普通文件\n");
}
//所有者对文件的操作权限
if(st.st_mode & S_IRUSR)
{
printf(" r\n");
}
if(st.st_mode & S_IWUSR)
{
printf(" w\n");
}
if(st.st_mode & S_IXUSR)
{
printf(" X\n");
}
return 0;
}
access function: included in the header file <unistd.h>
Role: Check file attributes
Function prototype: int access(const char *pathname, int mode);
Parameter pathname: the path of the file
Parameter mode: the attribute to check
Available options: R_OK, W_OK and X_OK
code example
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc, char* argv[])
{
if(argc < 2)
{
printf("a.out fileman\n");
exit(1);
}
//检测当前文件是否有写权限
int ret = access(argv[1], W_OK);
if(ret == -1)
{
perror("access");
exit(1);
}
printf("you can write this file.\n");
return 0;
}
chmod and chown functions
The role of the chmod function: modify file permissions
Function prototype: int chmod(const char *pathname, mode_t mode); included in the header file <sys/stat.h>
Parameter pathname: file path
Parameter mode: file permission, which is an octal number
The role of the chown function: modify the file owner and group
Function prototype: int chown(const char *pathname, uid_t owner, gid_t group); included in the header file <unistd.h>
Parameter pathname: file path
Parameter owner: integer value, user ID
Parameter group: integer value, group ID
opendir and readdir functions: included in the header file <dirent.h>
The role of the opendir function: open a directory
Opendir function prototype: DIR *opendir(const char *name);
Parameter name: directory name
Return value: pointer to directory
The role of the readir function: read the directory
The prototype of the readdir function: struct dirent *readdir(DIR *dirp);
Parameter dirp: return value of opendir
Return value: directory entry structure
dirent structure
struct dirent {
ino_t d_ino; //此目录进入点的inode
off_t d_off; //目录文件开头至此目录进入点的位移
unsigned short d_reclen; //d_name 的长度,不包含NULL 字符
unsigned char d_type; //d_name所指的文件类型
char d_name[256]; // 文件名
};
file type:
DT_BLK - block device
DT_CPR - character device
DT_DIR - directory
DT_LNK-soft link
DT_FIFO-Dad Road
DT_REG - normal file
DT_SOCK - socket
DT_UNKNOWN - Unknown
closedir function: close the directory
Function prototype: int closedir(DIR *dirp);
Program example
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<dirent.h>
//定义函数读指定目录中文件的个数
int getfile(const char* root)
{
int total = 0;
DIR* dir = NULL;
dir = opendir(root);
if(dir == NULL)
{
perror("opendir");
exit(0);
}
struct dirent* ptr;
while((ptr = readdir(dir)) != NULL)
{
//不处理 . 和 .. 目录
if(strcmp(".", ptr->d_name) == 0 || strcmp("..", ptr->d_name) == 0)
{
continue;
}
//判断是否是普通文件
if(ptr->d_type == DT_REG)
{
total++;
}
//判断是否是目录
if(ptr->d_type == DT_DIR)
{
//求出子目录
char path[1024] = {0};
sprintf(path, "%s/%s", root, ptr->d_name);//拼接子目录
total += getfile(path);
}
}
//关闭目录
closedir(dir);
return total;
}
int main(int argc, const char* argv[])
{
if(argc < 2)
{
printf("./a.out path\n");
exit(1);
}
int total = getfile(argv[1]);
printf("%s 目录下的普通文件个数:%d\n", argv[1], total);
return 0;
}
dup and dup2 functions: included header file <unistd.h>
The role of the dup function: copy the file descriptor
The function prototype of the dup function: int dup(int oldfd);
Parameter oldfd: the file descriptor to be copied
Return value: new file descriptor
The dup call is successful: there will be two file descriptors pointing to the same file
Return value: Take the smallest and unoccupied file description
The role of the dup2 function: file descriptor redirection
The prototype of the dup2 function: int dup2 (int oldfd, int newfd);
Parameter oldfd: if it points to hello
Parameter newfd: if it points to world
Calling the dup2 function will change newfd to point to the file pointed to by oldfd, that is, newfd will also point to hello's file -> file description redirection
When newfd is not occupied, newfd points to the file pointed to by oldfd