学习视频链接
黑马程序员-Linux系统编程_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1KE411q7ee?p=58&spm_id_from=pageDriver
目录
一、fcntl 函数
1.1 作用
改变一个已经打开的文件的访问控制属性
重点掌握两个参数的使用,F_GETFL 和 F_SETFL
1.2 查看函数介绍
1、man fcntl
2、fcntl
int flags = fcntl(fd, F_GETFL);
获取文件状态:F_GETFL
设置文件状态:F_SETFL
flags 的返回值为 -1 表示错误
flags 获取到了 fd 的权限的位图信息
3、位图
flags |= O_NONBLOCK 表示把位图中代表 O_NONBLOCK 的一位从 0 改为 1
使用 fcntl(fd, F_SETFL, flags) 函数再把原来的文件位图覆盖
位图的作用就是节约内存
1.3 测试运行
1、代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#define MSG_TRY "try again\n"
int main(void)
{
char buf[10];
int flags, n;
flags = fcntl(STDIN_FILENO, F_GETFL); // 获取stdin属性信息
if (flags == -1) {
perror("fcntl error");
exit(1);
}
flags |= O_NONBLOCK;
int ret = fcntl(STDIN_FILENO, F_SETFL, flags);
if (ret == -1) {
perror("fcntl error");
exit(1);
}
tryagain:
n = read(STDIN_FILENO, buf, 10);
if (n < 0) {
if (errno != EAGAIN) {
perror("read /dev/tty");
exit(1);
}
sleep(3);
write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
goto tryagain;
}
write(STDOUT_FILENO, buf, n);
return 0;
}
2、运行结果
1.4 其他的补充
fcntl(fd, F_SETFD, FD_CLOEXEC); // 这里设置为 FD_CLOEXEC 表示当程序执行 exec 函数时本 fd 将被系统自动关闭,表示不传递给 exec 创建的新进程,如果设置为 fcntl(fd, F_SETFD, 0); 那么本 fd 将保持打开状态复制到 exec创建的新进程中
二、lseek 函数
2.1 函数简介
1、off_t lseek(int fd, off_t offset, int whence)
2、参数
fd:文件描述符
offset:偏移量
whence:起始偏移量:SEEK_SET/SEEK_CUR/SEEK_END
3、返回值
成功:较起始位置偏移量
失败:-1 errno
2.2 测试运行
1、代码
2、运行
没有写出相应的内容
3、修改代码
2.4 代码逻辑
执行了写操作,读写指针的位置指向了最后。现在使用 lseek 把读写指针指向了开头,我们又能使用读写指针来读内容。
2.5 应用场景
(1) 文件的 “读”、“写”使用同一偏移位置
(2) 使用 lseek 获取文件大小
(3) 使用 lseek 拓展文件大小,想要使得文件大小真正的拓展,必须引起 IO 操作
1、获取文件大小
2、lseek 拓展文件大小
^@:相当于文件空洞,二进制形态为 "\0"
如果编写的时候编程这样也是可以的 write(fd, "\0", 1);
3、二进制形式查看
4、另一个用于拓展的函数
执行成功返回 0,并且源文件从 0 字节拓展到 250 字节了
三、Linux 查看文件二进制形式
3.1 txt 文件
6f —> o
e883 —> 胡
a1e5 —> 安
0a —> 换行
20 —> 空格
3.2 .c 文件
四、传入传出参数
4.1 传入参数
1、指针作为函数参数
2、同常有 const 关键字修饰
3、指针指向有效区域,在函数内部做读操作
4.2 传出参数
1、指针作为函数参数
2、在函数调用之前,指针指向的空间可以无意义,但必须有效
3、在函数内部,做写操作
4、函数调用结束后,充当函数返回值
4.3 传入传出参数
1、指针作为函数参数
2、在函数调用之前,指针指向的空间有实际意义
3、在函数内部,先做读操作,后做写操作
4、函数调用结束后, 充当函数返回值