标准C库的IO函数通常是可以跨平台的。标准C库会调用Linux操作系统提供的API。
文件描述符在进程的内核区的PCB(进程控制块)中的文件描述表中,通过系统调用返回给程序。文件描述符表是一个整型数组,默认大小是1024(也就是最多同时能打开1024个文件),前三个整型元素由系统占用,0表示STDIN,1表示STDOUT,2表示STDERR,每打开一个新文件就会占用一个文件描述符,而且是空闲的最小的一个文件描述符。调用Linux中的open方法就能够返回一个文件描述符。
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
// 打开一个已经存在的文件
// flags:对文件的权限设置以及其他的设置:O_RDONLY、O_WRONLY、O_RDWR(这三个权限互斥)
// 成功返回值是一个文件描述符,失败返回的是-1
int open(const char *pathname, int flags);
// 打开创建一个新的文件
// pathname:要创建的文件路径
// flags:对文件的操作权限和其他设置:
// - 必选项:O_RDONLY、O_WRONLY、O_RDWR(这三个权限互斥)
// - 可选项:O_CREATE:如果文件不存在则新建文件
// - flags是一个int型,32位,每一位就是一个标志位,所以如果要多个权限的话,使用逻辑|
// mode:八进制的数,表示创建出的新的文件的操作权限,比如:0777(0开头是八进制),最终的权限为:mode&~umask,umask的作用是抹去某些权限,使得权限更加合理
int open(const char *pathname, int flags, mode_t mode);
// errno:属于Linux系统函数库的,库里面的一个全局变量,记录的是最近的错误号
#include<stdio.h>
// 打印errno对应的错误描述
// s参数是用户描述,会在打印错误描述的时候一同打印出来
// 打印格式如下:s : errno
void perror(const char *s);
#include<unistd.h>
// 关闭一个文件描述符
int close(int fd);
#include<unistd.h>
// 将文件读进内存
// - fd:文件描述符,open得到
// - buf:需要读取数据存放的地方,传一个数组的地址,是一个传出参数
// - count:指定的数组的大小
// 返回0表示已经读到文件尾了,-1表示没有读取成功,>0表示返回了十几读取到的字节数
ssize_t read(int fd, void *buf, size_t count);
// 将数据写进文件
// - buf:要往磁盘写入的数据
// - count:要写的数据的实际的大小
// 成功:返回被写入的字节数量,失败,返回-1
ssize_t write(int fd, const void *buf, size_t count);
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
// 针对一个文件进行文件指针偏移,可以实现的操作有
// 1. 移动文件指针到头文件
// 2. 获取当前文件指针的位置
// 3. 获取文件长度
// 4. 拓展文件的长度
// - offset:off_t就是long,表示一个偏移量
// - whence:SEEK_SET(设置文件指针的偏移量,从头开始)、SEEK_END(文件大小+offset)、SEEK_CUR(从当前位置往后偏移offset)
// 返回文件指针的位置
off_t lseek(int fd, off_t offset, int whence)
#include <sys/stat.h>
// 获取一个文件的相关信息
// path:要操作的文件路径
// buf:是一个传出参数,保存获取到的文件信息(用一个stat的结构体保存)
// 成功,返回0,失败返回-1
// 获取的信息有:文件的设备编号、文件的类型和存取权限、硬链接数、用户ID、组ID、修改访问时间等
int stat(const char *restrict path, struct stat *restrict buf);
// 获取软连接的文件相关信息
int lstat(const char *restrict path, struct stat *restrict buf);
// 用于判断某个文件是否有某个权限,或者检查某个文件是否存在
// - mode:R_OK、W_OK、X_OK、F_OK(判断文件是否存在)
// 成功返回0, 失败返回-1
int access(const char* pathname, int mode);
// 用于修改一个文件的权限
int chmod(const char* pathname, int mode);
// 改变文件所有者
int chown(const char* pathname, uid_t owner, gid_t group);
// 用于缩减或者扩展文件的尺寸到指定大小
// - len:需要最终文件变成的大小
int truncate(const char* path, off_t len);
#include<sys/stat.h>
#include<sys/type.h>
// 新建一个文件夹,指定权限(八进制数)
// 成功返回0,失败返回-1
int mkdir(const char* pathname, mode_t mode);
// 删除一个文件夹
int rmdir(const char* pathname);
// 重命名一个文件夹/文件
int rename(const char* oldpath, const char* newpath);
// 修改进程当前工作目录
int chdir(const char* pathname);
// 获取当前的工作路径
// - buf:是传出参数
// - size:指定buf数组的大小
// 返回指向buf的首地址
char *getcwd(char* buf, size_t size);
#include<dirent.h>
#include<sys/types.h>
// 打开一个目录流
// - name:需要打开的目录的名称
// 返回一个指针,指向一个目录流,错误的话返回NULL
DIR* opendir(const char* name);
// 读取目录中的数据,调用一次,目录流指针将会指向下一个实体
// 读取到目录末尾或者失败返回NULL,成功则返回结构体dirent
struct dirent *readdir(DIR *dirp);
// 关闭一个目录流
int closedir(DIR *dirp);
#include<unistd.h>
// 复制文件描述符,将oldfd替换成当前可用的最小的文件描述符,这个新的文件描述符也指向oldfd指向的文件
// 返回这个最小的文件描述符
int dup(int oldfd);
// 重定向文件描述符
// 调用成功后,newfd指向的文件会close,并将newfd指向oldfd指向的文件
// 返回值是newfd
int dup2(int oldfd, int newfd);
// fcntl根据cmd行为不同
// 当cmd为F_DUPFD时,操作就和dup相同
// 还可以修改文件描述符状态、标志:
// - F_GETFL:获取指定文件描述符文件状态flag,获取的flag和我们通过open函数传递flag相同
// - F_SETFL:设置文件描述符文件状态flag,其实就是文件的权限
// 必选项:O_RDONLY、O_WRONLY、O_RDWR
// 可选项:O_APPEND(追加数据),O_NONBLOCK(IO非阻塞)
int fcntl(int fd, int cmd, .../* arg */);