read函数:#include<fctnl.h>
ssize_t read(int fd,void* buf,size_t count);
fd:文件描述符
buf:存数据的缓冲区
count:缓冲区大小
返回值:
0:表示读到文件末尾
成功:读到的字节数
失败:-1 设置errno
-1 并且 errno=EAGIN 或EWOULDBLOCK,说明不是read失败,而是read在以非阻塞读一个设备文件,或网络文件
write函数#include<unistd.h>
ssize_t write(int fd,const void* buf,size_t count);
fd:文件描述符
buf:存数据的缓冲区
count:缓冲区大小
返回值:
成功:读到的字节数
失败:-1 设置errno
错误处理函数
void perror(const char*s);
perror("open error\n");
补充strace命令 跟踪系统级调用
系统调用和库函数比较——fputc和read
缓冲区
read,write函数常常被称为 Unbuffered I/O。指的是无用户级缓冲区
fputc自带缓冲区,虽然每次读一个字节,但是这个字节是存在自己 的缓冲区里面,满了之后再送到内核区
文件描述符
PCB进程控制块:本质 结构体
struct task_struct{结构体}
成员:文件描述符表
文件描述符:0/1/2.../1024
0-STDIN_FILENO
1-STDOUT_FILENO
2-STDERR_FILENO
最大打开文件数:一个进程默认打开文件的个数是1024个
命令查看:ulimit -a查看open files对应值。默认是1024
修改i:ulimit -n 4096
阻塞、非阻塞:是设备,网络文件的属性
产生阻塞的场景:读设备文件(/dev/tty--终端文件),读网络文件。(读常规文件无阻塞概念)
open("/dev/tty",O_RDWR|O_NONBLOCK); ---设置/dev/tty/非阻塞状态,默认是阻塞状态
fcntl函数
int flags=fcnt(fd,F_GETFL);
位图
flags |=O_NONBLOCK;
改变一个【已经打开】的文件的访问控制属性
F_GETFL 获取文件状态信息
F_SETFL 设置文件状态
修改文件属性
flags=fcntl(fd,F_GETFL);
flags |=O_NONBLOCK;
fcntl(fd,F_SETFL,flags);
lseek函数:文件偏移
off_t lseek(int fd,off_t offset,int whence);
参数:
fd:文件描述符
offset:偏移量
whence:起始偏移位置
返回值:
成功:起始位置偏移量
失败:-1 errno
应用场景:
1.文件的“读”,“写”使用同一偏移位置
2.使用lseek获取,拓展文件大小
3.使用lseek拓展文件大小,想要真正的扩展,必须引起IO操作
使用truncate函数,直接拓展文件大小 int ret=truncate("dict.cp",250);
传入参数:
1.指针作为函数参数
2.常有const关键字修饰
3。指针指向有效区域,在函数内部做读操作
传出参数:
1.指针作为函数参数
2.在函数调用之前,指针指向的空间可以无意义,但必须有效
3.在函数内部,做写操作
4.函数调用结束后,充当函数
传入传出参数:
1+3:在函数内部做读写操作
目录项和inode
stat函数(会穿透符号链接)
int stat(const char*path,struct stat *buf)
参数:
path:文件路径
buf:(传出参数)存放文件属性
返回值:
成功:0
失败:-1 errno
获取文件大小:buf.st_size
获取文件类型:buf.st_mode
获取文件权限:buf.st_mode
lstat函数(不会穿透符号链接)
link函数
创建硬链接(命令):ln t.c t.hard
unlink函数
清除文件时,如果文件的硬链接数到0了。没有dentry对应,但该文件不会立马释放,要等到所有打开该文件的进程关闭该文件,系统才会挑时间将文件释放掉
readlink函数
读取符号链接文件本身内容,得到链接所指向的文件名
ssize_t readlink(const char* path,char *buf,size_t bufsize);
dup2函数
#include <unistd.h>
#include <fcntl.h>
int dup2(int oldfd, int newfd);
返回值:
成功:新的文件描述符
失败:-1
目录操作
DIR* opendir(char* name);
int closedir(DIR *dp);
struct dirent *readdir(DIR *dp);
struct dirent {
inode
char name[256];
}
#include<stdio.h>
#include<stdlib.h>
#include<dirent.h>
#include<unistd.h>
int main(int argc,char *argv[])
{
DIR *dp;
struct dirent *sdp;
//打开目录
dp=opendir(argv[1]);
if(dp==NULL )
{
perror("opendir error");
exit(1);
}
//读取目录并显示
while((sdp=readdir(dp))!=NULL ){
printf("%s\t",sdp->d_name);
}
printf("\n");
//关闭目录
closedir(dp);
return 0;
}