当遇到不明白的函数都可以用man命令查询
man 手册第一部分是命令 man 1 printf
man 手册第二部分是系统调用 man 2 write
man 手册第三部分是库函数 man 3 printf
以下介绍的文件操作函数全部都属于系统调用函数
另外需要错误信息可以调用strerror()和perror()
perror(“Oen failure”);
printf(“Open failure: %s\n”, strerror(errno));
虽然perror使用简单,但是我们常用后者
对于内核而言,所有打开的文件、设备、网络socket都是通过文件描述符引用,文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,使用open或creat返回的文件描述符标识该文件,将其作为参数传给read或write。
应用程序运行的时候,系统将会为该进程默认打开三个文件描述符:
标准输入: STDIN_FILENO (0)
标准输出: STDOUT_FILENO (1)
标准出错: STDERR_FILENO (2)
文件描述符的变化范围是: 0~OPEN_MAX-1
int open(const char *path, int oflag, *mode*);
返回值 int fd 文件描述符(file description), open系统调用返回的文件描述符一定是最小的、未使用的文件描述符数值。即3,因为0标准输入,1标准输出,2标准出错系统默认会打开。
参数:
1.*path: 要打开的文件、设备的路径名
2.**oflag: ** 由多个选项进行 或 运算构造oflag参数
必选:O_RDONLY (只读)、 O_WRONLY(只写)、 O_RDWR(读写)
可选:O_APPEND 每次写时都追加到文件的尾端。
O_CREAT 文件不存在则创建它,使用该选项需要第三个参数mode
O_NONBLOCK 如果path是一个FIFO、块设备、字符特殊文件则此选项为文件的本次打开和后续的I/O操作设置非阻塞模式方式。
O_TRUNC 如果文件存在,而且为只写或读写成功打开,则将其长度截取为0;
O_EXEC、O_SEARCH、O_CLOEXEC、O_NOCTTY…
3.mode: oflag带O_CREAT选项时,必须带该参数用来指定打开文件的权限模式,如066。
int creat(const char *path, mode_t mode);
此函数用来创建一个新文件并返回其fd。它等价于
open(path, O_WRONLY|O_CREAT|O_TRUNC, mode);
int close(int fd);
该函数用来关闭一个打开的文件,关闭一个文件时还会释放该进程加在该文件上的所有记录锁。当一个进程终止时,内核自动关闭它所有打开的文件。
ssize_t write(int fd, const void *buf, size_t nbytes);
如write成功,则返回实际写入的字节数,失败返回-1。
ssize_t read(fd,buf,sizeof(buf));
如果返回fd小于0说明读文件错误,可以用streror(errno)获取错位原因
如read成功,则返回读到的字节数。如已到达文件的尾端,则返回0。
read之前必须清空buff
menset(buf,0,sizeof(buff);
另外如果先使用了write()函数,要把文件偏移量(即光标位置)调到开头,这里用到 lseek()函数,下面介绍,或者在使用open()时加O_APPEND
每打开一个文件时都有一个与其关联的“当前文件偏移量”。它通常是一个非负整数,用以度量从文件开始处计算的字节数。通常读写操作都是从当前文件偏移量处开始,并使用偏移量增加所读写的字节数。
按系统默认的情况,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0.
off_t lseek(int fd, off_t offset, int whence);
whence:
SEEK_SET, 则将该文件偏移量设置为距文件开始处offset个字节;
SEEK_CUR,则该文件的偏移量设置为当前值加offset,offset可为正或负;
SEEK_END,则将该文件偏移量设置为长度加offset,offset可正可负;
int dup(int fd);
int dup2(int fd, int fd2);
例如
int fd = -1;
fd = open(“std.txt”, O_RDWR|O_CREAT|O_TRUNC, 0666);
dup2(fd, STDOUT_FILENO);
printf(“Hello Word!\n”); //标准输出就会关闭,hello world会被输出重定向到文件fd即std.txt中
使用这两个函数可以用来实现标注输入、标准输出、标准出错重定向
ioctl()函数一直是I/O操作的杂物箱,不能用本章中其他函数表示的I/O操作通常都能用ioctl()表示。终端I/O、设备I/O是使用ioctl()最多的地方。
int ioctl(int fd, int cmd, ...);
fd: 文件描述符
cmd: 命令字,这个参数需要与设备驱动中的cmd保持一致。
第三个参数可选
这两个函数都是用来返回文件或目录的相关信息,
只是stat()的第一个参数是文件名,
而fstat()的第一个参数是文件打开的相应文件描述符。
int stat(const char * restrict path, struct stat *restrict buf);
int fstat(int fd, struct stat *buf);
access可以用来测试文件是否存在或测试其权限位:
int access(const char *path, int mode);
例子1 测试文件是否存在:
if( !(access(“test.txt”, F_OK)) ) // 返回0表示存在;返回-1表示不存在。
{
printf(“File exist\n”);
}
例子2 测试文件是否可读可写:
if( !(access(”test.txt”, R_OK|W_OK)) ) // 返回0表示存在;返回-1表示不存在。
{
printf(“File mode is read/write \n”);
}
int unlink(const char *path);
该系统调用可以用来删除文件
调用该函数将path指定的文件的链接数减1,如果对该文件还有其他链接存在,则仍可以通过其他链接访问该文件的数据。
只有当链接记数达到0时,该文件的内容才可被删除。如果有进程打开了该文件,其内容也不能被删除。关闭一个文件时,内核首先检查打开该文件的进程个数,如果这个记数达到0,内核再去检查它的链接记数,如果记数也是0,那么就删除该文件内容。
int rename(const char *oldname, const char *newname);
调用该函数可以实现文件的重命名。
创建文件夹:
int mkdir(const char *pathname, mode_t mode);
删除文件夹:
int rmdir(const char *pathname);
打开文件夹:
DIR *opendir(const char *pathname);
读文件夹:
struct dirent * readdir(DIR *dp);
关闭文件夹:
int closedir(IDR *dp);
改变工作目录:
int chdir(const char * pathname);