open函数
int open(const char *pathname, int flags);
int open(const char *pathname,int flags, mode_t mode);
pathname 文件路径。
flags 权限控制,只读,只写,读写。 O_RDONLY, O_WRONLY, O_RDWR #include <fcntl.h>
mode: 参数 3 使用的前提, 参 2 指定了 O_CREAT。 取值 8 进制数,用来描述文件的 访问权限。例如:rwx => 0664
read 函数 & write 函数
ssize_t read(int fd, void *buf, size_t count);
fd:文件描述符。
buf:存数据的缓冲区。
count:缓冲区大小。
返回值:
0:读到文件末尾。
成功; > 0 读到的字节数。
失败: -1, 设置 errno。
-1: 并且 errno = EAGIN 或 EWOULDBLOCK, 说明不是 read 失败,而是 read 在以非阻塞方
式读一个设备文件(网络文件),并且文件无数据。
ssize_t write(int fd, const void *buf, size_t count);
参数同上。
*与io库函数fgetc / fputc对比:
read / write 这块,每次写固定设置字节,字节过小会疯狂进行内核态和用户态的切换,所以非常耗时。
fgetc / fputc,有个缓冲区,默认4096,所以它并不是一个字节一个字节地写,内核和用户切换就比较少,并且有预读入,缓输出机制。
*阻塞、非阻塞:
当读取 STDIN_FILENO 默认会阻塞等待输入。
若将读取终端文件改为 fd = open("/dev/tty", O_RDONLY|O_NONBLOCK); 则为非阻塞状态。
fcntl 命令
int fcntl(int fd, int cmd, ...);
fd 文件描述符。
cmd 命令,决定了后续参数个数,例如获取文件状态 F_GETFL、设置文件状态 F_SETFL。
// 将STDIN_FILENO设置为非阻塞
flags = fcntl(STDIN_FILENO, F_GETFL);
flags |= O_NONBLOCK;
fcntl(STDIN_FILENO, F_SETFL, flags);
lseek 函数
应用场景:
1. 文件的“读”、“写”使用同一偏移位置。
2. 使用 lseek 获取文件大小。
3. 使用 lseek 拓展文件大小:要想使文件大小真正拓展,必须引起 IO 操作。
使用 truncate 函数,直接拓展文件。 int ret = truncate("dict.cp", 250);
off_t lseek(int fd, off_t offset, int whence);
fd:文件描述符。
offset: 偏移量,就是将读写指针从 whence 指定位置向后偏移 offset 个单位。
whence:起始偏移位置: SEEK_SET/SEEK_CUR/SEEK_END。
stat 函数 & lstat 函数
获取文件属性(从 inode 结构体中获取)。如果文件不是链接文件,则二者没有区别,如果是链接文件有如下区别:
stat:获取链接文件的信息时,具有穿透能力,直接穿越链接文件,获取所被链接文件的信息。
lstat:获取链接文件的信息,无穿透能力。
int stat(const char *path, struct stat *buf);
path: 文件路径
buf:(传出参数) 存放文件属性,inode 结构体指针。
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main( int argc, char *argv[]){ //执行./main filepath
struct stat sbuf;
int ret = stat(argv[1], &sbuf);
if ( ret == -1){
perror( "stat error" );exit(1);
}
printf("file size: %ld\n" , sbuf.st_size);
return 0;
}
获取文件大小: buf.st_size
获取文件类型: buf.st_mode
获取文件权限: buf.st_mode
等。
link函数 & unlink 函数
link 用来创建硬链接的:int link(const char *oldpath, const char *newpath);
unlink 是删除一个文件的目录项 dentry,使硬链接数-1:int unlink(const char *pathname);
*unlink 函数的特征:清除文件时,如果文件的硬链接数到 0 了,没有 dentry 对应,但该文件仍不会
马上被释放,要等到所有打开文件的进程关闭该文件,系统才会挑时间将该文件释放掉。
*隐式回收:close(fd); 当进程结束运行时,所有进程打开的文件会被关闭,申请的内存空间会被释放。系统的这一特性称之为隐式回收系统资源。没有隐式回收的话,这个文件描述符会保留,多次出现这种情况会导致系统文件描述符耗尽。所以隐式回收会在程序结束时收回它打开的文件使用
的文件描述符。
目录操作函数
打开目录:DIR* opendir(char *name);
关闭文件夹:int closedir(DIR *dp);
读文件夹:struct dirent *readdir(DIR * dp);
结构体:
struct dirent {
inode;
char dname[256];
}
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread .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 ( "%slt", sdp->d_name) ; // 遍历文件夹内容
}
closedir(dp);
return 0;
}
dup 函数 & dup2 函数
本质就是复制文件描述符,用来做重定向。
int dup(int oldfd);
oldfd: 已有文件描述符。
返回:新文件描述符,这个描述符和 oldfd 指向相同内容。
int dup2(int oldfd, int newfd);
oldfd 拷贝给 newfd。返回 newfd。
*fcntl 函数实现 dup:
dup(oldfd) == > fcntl(oldfd, F_DUPFD, 0) //此新创建描述符是当前可用文件描述符的最小数值
dup2(oldfd, newfd) ==> close(oldfd);fcntl(oldfd, F_DUPFD, newfd);
2134

被折叠的 条评论
为什么被折叠?



