1.打开和关闭文件
1.1 open
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include<unistd.h> #include<fcntl.h> int open(const char *pathname, int flags)
int open(const char* pathname, int flags, mode_t mode)
|
注意,文件创建后的最终权限受到 open() 函数传入的参数影响,同时也受到 umask 屏蔽掩码共同影响
最终创建出的文件权限 = mode & (~umask)
1.2 close
1 2 3 4 5 6
| #include <unistd.h> int close(int fd)
|
2.文件读取和写入
read和write都是按字节操作的函数
2.1 read
1 2 3 4 5 6 7 8 9 10 11 12 13
| ssize_t read(int fd, void *buf, size_t count)
|
2.2 write
1 2 3 4 5 6 7 8 9
| ssize_t write(int fd, void *buf, size_t count)
|
2.3 与fgetc和fputc比较
read 和 write 是系统调用,fgetc 和 fputc 是 c 语言提供的函数。下面两个函数举例,同样复制一个txt文件,每次复制一个字节,c 语言提供的函数速度会远远快于系统调用,因为 c 语言封装的 read 和write 有一个缓冲区,分别是预读入和缓输出,虽然 fgetc 函数读取一个字节,但实际上它一次性会缓存4096字节在内存中,同样 fputc 虽然会写入一个字节,但它会先写入内存4096字节再一次性写入文件,这种机制避免了频繁IO降低性能
2.4 文件描述符
PCB进程控制块里有一个成员是文件描述符表,open 函数返回的 fd 是一个下标,返回表中未被使用的最小的文件描述符(0、1、2分别是标准输入STDIN_FILENO、标准输出STDOUT_FILENO、标准出错STDERR_FILENO)
3. 错误代码处理
3.1 strerror
3.2 perror
1 2 3 4 5 6
| int fd = open(filepath, O_RDWR|O_CREAT|O_TRUNC, 0644); if(fd == -1) { perror("open dst err"); exit(1); }
|
4.改变已经打开文件的访问属性
4.1 fcntl (f control)
这个函数功能非常多,这只是一个例子
1 2 3 4 5 6 7 8
| #include <fcntl.h> int fcntl(int fd, int cmd, ...);
int flag = fcntl(fd, F_GETFL);
flag |= O_NONBLOCK;
fcntl(fd, F_SETFL, flag);
|
5.改变文件指针
5.1 lseek
1 2 3 4 5 6 7 8
| off_t lseek(int fd, off_t offset, int whence);
|
- 文件的“读”、“写”使用相同偏移位置,所以先使用 write 写入10个字节后,read 时指针也是在第10个字节开始的,这可能就需要 lseek 调整指针位置
- 可以通过 int len = lseek(fd, 0, SEEK_END); 获取当前文件的大小,从结束位置偏移 0 个字节返回
- 可以通过 int len = lseek(fd, 10, SEEK_END); 拓展文件大小,但必须引起IO操作才能拓展,write(fd, “a”, strlen(“a”)); 正常应该用 truncate() 函数扩展文件大小
Author:
mxwu
Permalink:
https://mingxuanwu.com/2023/10/27/202310271715/
License:
Copyright (c) 2023 CC-BY-NC-4.0 LICENSE