文件系统
硬链接:本质是文件名,目录文件IJ点中的一条。
软连接:存放了另一个文件的硬链接的文件
4、内核缺省为每个进程打开三个文件描述符(>=0且<OPEN_MAX的整数):
0 - 标准输入
1 - 标准输出
3 - 标准出错
|#define STDIN_FILENO 0 //0<i.txt 输入重定向
|#define STDOUT_FILENO 1
|#define STDERR_FILENO 2 // 2>/dev/null 错误重定向
例:./a.out 0<i.txt 1>o.txt 2>e.txt
stderr 跟 stdout的区别:其它的区别没有。
1、stdout 有缓冲。因为出错要尽快的显示出来。
文件系统 文件系统 文件系统
文件的数据和属性:
属性:创建时间、属主,属组等等。
open/creat 返回的一定是当前未使用的最小的文件描述符。
|#include <unistd.h>
int close(int fd);
成功返回0 ,失败返回-1.
|#include <stdio.h>
|#include <fcntl.h> //声明了文件操作函数
int main(void){
int fd1 = open("open.txt", O_RDWR | O_CREAT | O_TRUNC, 0666); //出来是664,
//跟权限掩码umask(0002)的反进行与操作
if(fd1 == -1){
perror("open");
return -1;
}
printf("fd1 = %d\n", fd1); //打印出来3,最小未使用的文件描述符
closed(fd1);
return 0;
}
6、write
|#include<unistd.h>
ssize_t write( //返回有符号的整数,兼容性好,不用int
int fd,
const void* buf,
size_t count //无符号的整数,因为返回值是有符号的整数,所以不要超过。
);
成功返回实际写入的字节数(0字节表示未写入,可能往网络写),失败返回-1。
|#include <stdio.h>
|#include <fcntl.h>
|#include <string.h>
|#include <unistd.h>
int main(void){
int fd = open("write.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if(fd == -1){
perror("open");
return -1;
}
const char* text = "hello , world !";
size_t towrite = strlen(text) * sizeof(char); //为了可移植性,乘多一个sizeof
ssize_t written = write(fd, text, towrite); //当返回值比期望值小的时候,
//应该继续写入剩下的字符
if(written == -1){
perror("write");
return -1;
}
clode(fd);
return 0;
}
7、read
|#include <stdio.h>
|#include <string.h>
|#include <unistd.h>
|#include <fcntl.h>
int main(void){
int fd = open ("read.txt", O_RDONLY);
if(-1 == fd){
perror("open");
return -1;
}
char text[256] = {}; //初始化为0,防止文本结尾没有\0
size_t toread = sizeof(text);
ssize_t readed = read (fd, text, toread);
if(readed == -1){
perror("read");
return -1;
}
//text[readed/sizeof(text[0])] = '\0';
printf("读取内容:%s\n", text); //vi写出来的文本没有\0
return 0;
}
八、系统I/O与标准IO
1、当系统调用函数被执行时,需要切换用户态和内核态,频繁调用会导致性能损失。
2、标准库做了必要的优化,内部维护了一个缓冲区,
只在满足特定的条件时才将缓冲区与系统内核同步,
借此降低执行系统调用的频率,
减少进程在用户态和内核态之间来回切换的次数,
提高运行性能。
文件系统 文件系统 文件系统
所以标准io比系统io感觉用起来效率更高。
文件系统 文件系统 文件系统
9、lseek
可以通过预编译查看原始类型, gcc -E xxx
lseek只是移动当前位置,并不修改文件,也没有I/O。
当移到文件末尾还要靠后的位置,再次进行写入。则会出现空洞。@@@@@@@@,会占文件大小,但不会在硬盘上存储。
9.1、获得文件大小
1、fseek获得文件尾,ftell 获取当前文件位置。
2、lseek移动0 个,第三个参数使用SEEK_END得出当前文件尾(既是文件大小)。
10、打开文件的内核数据结构
通过ls -i可以查看i节点号。
i节点记录了文件的属性和数据在磁盘上的存储位置。
目录也是文件,存放路径和i节点号的映射表。
每一个打开的文件描述符有个对应的指针指向文件表。
文件表存放文件偏移,v节点指针,指向v节点信息和i节点信息。文件大小存放在i节点中。
文件系统:数据结构加管理软件
gcc -g 生成调试可执行问及爱你
gdb ./a.out
b 14 设置断点。
n 执行下一条命令
p x 打印
printf往文件描述符为1 的文件里面写,scanf是往未见描述符为0的文件里面写。
并不一定就是显示器,可以重定向。
两次打开同一个文件,返回的是两个个文件描述符,指向两个不同的文件表,1个v节点,一个i节点。修改lseek不影响另外一个文件描述符。
int dup(int oldfd);
int dup2(int oldfd, int newfd);
返回文件描述符的副本。两个文件描述符,对应同一个文件表。修改lseek会影响另一个文件描述符。
什么时候用?多进程的时候,复制父进程的文件描述符。同以往一个文件里面写,不想互相覆盖,则使用dup。
作业:学生管理系统登陆模块
注册 --增加
登陆 --验证
用户信息保存在文件中。
文件系统 文件系统 文件系统 文件系统 文件系统 文件系统 文件系统
- linux查看文件描述符表
cat /proc/对应进程pid/fd