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 可读可写打开
O_APPEND 表示追加 O_CREAT 若此文件不存在则创建它。
O_NONBLOCK 对于设备文件, 以 O_NONBLOCK 方式打开可以做非阻塞
成功: 返回一个最小且未被占用的文件描述符 失败: 返回-1, 并设置 errno 值.
close 函数
函数描述: 关闭文件
函数原型: int close(int fd);
fd 文件描述符
函数返回值:
成功返回 0
失败返回-1, 并设置 errno 值.
read 函数
函数描述: 从打开的设备或文件中读取数据
函数原型: ssize_t read(int fd, void *buf, size_t count);
fd: 文件描述符
buf: 读上来的数据保存在缓冲区 buf 中
count: buf 缓冲区存放的最大字节数
函数返回值:
>0:读取到的字节数
=0:文件读取完毕
-1: 出错,并设置 errno
write
函数描述: 向打开的设备或文件中写数据
函数原型: ssize_t write(int fd, const void *buf, size_t count);
fd:文件描述符
buf:缓冲区,要写入文件或设备的数据
count:buf 中数据的长度
函数返回值: 成功:返回写入的字节数 错误:返回-1 并设置 errno
lseek
所有打开的文件都有一个当前文件偏移量(current file offset),以下简称为 cfo. cfo 通常是 一个非负整数, 用于表明文件开始处到文件当前位置的字节数. 读写操作通常开始于 cfo, 并且使 cfo 增大, 增量为读写的字节数. 文件被打开时, cfo 会被初始化为 0, 除非使用了 O_APPEND. 使用 lseek 函数可以改变文件的 cfo.
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
fd:文件描述符
参数 offset 的含义取决于参数 whence:
◆ 如果 whence 是 SEEK_SET,文件偏移量将设置为 offset。
◆ 如果 whence 是 SEEK_CUR,文件偏移量将被设置为 cfo 加上 offset,offset 可以为正也可以为负。
◆ 如果 whence 是 SEEK_END,文件偏移量将被设置为文件长度加上 offset, offset 可以为正也可以为负。
lseek 函数常用操作
➢ 文件指针移动到头部 lseek(fd, 0, SEEK_SET);
➢ 获取文件指针当前位置 int len = lseek(fd, 0, SEEK_CUR);
➢ 获取文件长度 int len = lseek(fd, 0, SEEK_END);
➢ lseek 实现文件拓展 off_t currpos; // 从文件尾部开始向后拓展 1000 个字节
currpos = lseek(fd, 1000, SEEK_END); // 额外执行一次写操作,否则文件无法完成拓展 write(fd, “a”, 1); // 数据随便写
stat/lstat 函数 :
函数描述: 获取文件属性
函数原型:
int stat(const char *pathname, struct stat *buf);
int lstat(const char *pathname, struct stat *buf);
成功返回 0 失败返回 -1
stat 函数和 lstat 函数的区别
➢ 对于普通文件, 这两个函数没有区别, 是一样的.
➢ 对于连接文件,调用 lstat 函数获取的是链接文件本身的属性信息;
而 stat 函数获取的是链接文件指向的文件的属性信息.
目录操作相关函数
opendir 函数
函数描述:打开一个目录
◼ 函数原型: DIR *opendir(const char *name);
◼ 函数返回值: 指向目录的指针
◼ 函数参数: 要遍历的目录(相对路径或者绝对路径)
readdir 函数
◼ 函数描述: 读取目录内容--目录项◼ 函数原型: struct dirent *readdir(DIR *dirp);
◼ 函数返回值: 读取的目录项指针
◼ 函数参数: opendir 函数的返回值
struct dirent {
ino_t d_ino; // 此目录进入点的
inode off_t d_off; // 目录文件开头至此目录进入点的位移
signed short int d_reclen; // d_name 的长度, 不包含 NULL 字符
unsigned char d_type; // d_name 所指的文件类型
char d_name[256]; // 文件名
};
d_type 的取值:➢ DT_BLK - 块设备
➢ DT_CHR - 字符设备
➢ DT_DIR - 目录
➢ DT_LNK - 软连接
➢ DT_FIFO - 管道
➢ DT_REG - 普通文件
➢ DT_SOCK - 套接字
➢ DT_UNKNOWN - 未知
closedir 函数
◼ 函数描述: 关闭目录
◼ 函数原型: int closedir(DIR *dirp);
◼ 函数返回值: 成功返回 0, 失败返回-1
函数参数: opendir 函数的返回值
读取目录内容的一般步骤
1 DIR *pDir = opendir(“dir”); //打开目录2 while((p=readdir(pDir))!=NULL){} //循环读取文件
3 closedir(pDir); //关闭目录
dup 函数
➢ 函数描述: 复制文件描述符➢ 函数原型: int dup(int oldfd);
➢ 函数参数: oldfd -要复制的文件描述符
➢ 函数返回值:
◆ 成功: 返回最小且没被占用的文件描述符
◆ 失败: 返回-1, 设置 errno 值
dup2 函数
➢ 函数描述: 复制文件描述符➢ 函数原型: int dup2(int oldfd, int newfd);
➢ 函数参数: ◆ oldfd-原来的文件描述符
◆ newfd-复制成的新的文件描述符
➢ 函数返回值:
◆ 成功: 将 oldfd 复制给 newfd, 两个文件描述符指向同一个文件
◆ 失败: 返回-1,
设置 errno 值 ➢ 假设 newfd 已经指向了一个文件,
首先 close 原来打开的文件,
然后 newfd 指向 oldfd 指向 的文件. 若 newfd 没有被占用,newfd 指向 oldfd 指向的文件.
fcntl 函数
函数描述: 改变已经打开的文件的属性
➢ 函数原型: int fcntl(int fd, int cmd, ... /* arg */ );
◆ 若 cmd 为 F_DUPFD, 复制文件描述符, 与 dup 相同
◆ 若 cmd 为 F_GETFL, 获取文件描述符的 flag 属性值
◆ 若 cmd 为 F_SETFL, 设置文件描述符的 flag 属性
➢ 函数返回值:返回值取决于 cmd
◆ 成功
若 cmd 为 F_DUPFD, 返回一个新的文件描述符
若 cmd 为 F_GETFL, 返回文件描述符的 flags 值
若 cmd 为 F_SETFL, 返回 0
◆ 失败返回-1, 并设置 errno 值.
fcntl 函数常用的操作:
1 复制一个新的文件描述符: int newfd = fcntl(fd, F_DUPFD, 0);
2 获取文件的属性标志 int flag = fcntl(fd, F_GETFL, 0)
3 设置文件状态标志 flag = flag | O_APPEND; fcntl(fd, F_SETFL, flag)
4 常用的属性标志 O_APPEND-----设置文件打开为末尾添加 O_NONBLOCK-----设置打开的文件描述符为非阻塞