目录:
1. C语言文件接口(库函数)
C语言文件接口函数有:fopen/fclose/fread/fwrite/fseek等
1.1 fopen
FILE *fopen(const char *path, const char *mode);
- path:带路径的文件名称(待打开的文件)
- mode:
r:以可读方式打开,不可写,文件不存在,则报错
r+:以读写方式打开,文件不存在,则报错
w:以可写方式打开,但是不能读。文件不存在,则创建。文件存在,则截断(清空文件内容)文件。
w+:以读写方式打开。文件不存在,则创建。文件存在,则截断(清空文件内容)文件
a:追加写,不能读。在文件末尾进行追加写,文件不存在则创建文件。文件存在,则在文件末尾开始写
a+:可读追加写,在文件末尾进行追加写,文件不存在则创建文件。文件存在,则在文件的末尾进行追加写
- 返回值:文件流指针 FILE
如下以"W+"为例测试:
如下图所示当前路径下没有test.txt文件
我们调用一个fopen函数并让它以w+方式打开一个文件
如下图所示,我们会发现当前路径下创建了一个test.txt文件
1.2 fclose
int fclose(FILE *fp);
关闭一个文件流指针
1.3 fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- ptr:要将读到的保存到哪里去,ptr保存用户准备的一个空间(缓冲区)的地址
- size:块的大小,单位是字节
- nmemb:块的个数
eg:size = 2 nmemb = 5 ==> 10
常见的用法:size = 1,nmemb可以指定任意块,读到的字节数量也就可以用nmemb表示
- stream:文件流指针,表示要从哪里进行读
- 返回值:返回读到的块的个数
测试如下:
首先我们先在上面的test.txt文件中写入一些内容,便于查看测试结果
我们调用一个fread函数,让他从test.txt文件中读内容到buf中
如下图所示我们可以查看到读入到buf中的内容
1.4 fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
- ptr:要写入到文件当中的内容
- size:块的大小,单位字节
- nmemb:块的个数
总写入的字节数量 = 块的大小 * 块的个数
- stream:文件流指针,表示要写到哪里
- 返回值:写入块的个数
测试如下:
调用fwrite函数,将buf中的内容写入到test.txt文件中
打开test.txt文件我们会看到我们刚才写入到”linux is so easy“
1.5 fseek
int fseek(FILE *stream, long offset, int whence);
- stream:文件流指针
- offset:偏移量,单位字节。相对于whence而言的偏移量
- whence:
SEEK_SET:文件的头部
SEEK_CUR:当前文件流指针的位置
SEEK_END:文件的尾部
测试如下:
我们先将一段内容写入文件中,再读,代码如下图所示:
此时我们会发现,虽然代码已经写入fp,但却从fp中读不出内容,这是为什么呢?因为文件流指针会发生偏移,当我们写完内容后文件流指针会指向,最后一个字节的下一个位置,而此时再读取文件内容,会从文件流指针向后读取,而我们只需让文件流指针指向文件的头部即可读出内容
2. 系统调用的文件接口
系统调用的文件接口有:open/close/read/write/lseek等
2.1 open
int open(const char *pathname, int flags);
若目标文件不存在,需要open创建使用:
int open(const char *pathname, int flags, mode_t mode);
- mod_t:表示创建文件的默认权限(使用八进制数字表示)
eg:0777
- pathname:待要打开的文件名
- flags:
(1)O_RDONLY:只读方式
(2)O_WRONLY:只写方式
(3)O_RDWR:读写方式
(1)(2)(3)有且只能有一个,互相是互斥的
(4)O_CREAT:文件不存在可以创建
(5)O_TRUNC:截断文件(清空文件)
(6)O_APPEND:追加
(4)(5)(6)可以与(1) | (2) | (3)组合使用
组合使用的方式:按位或
eg:O_WRONLY | O_CREAT | O_TRUNC
- 返回值:返回一个正整数,含义为文件描述符
测试如下:
如上图所示的测试结果我们会发现,文件权限不是我们预期的权限,而我们想要达到预期权限就得使用三个参数的open,第三个参数表示创建文件的默认权限
而此时我们会发现文件权限和我们创建设置的默认权限并不完全相同,通过查看man手册我们发现,文件权限mode & ~umask才是最终文件的权限
2.2 close
int close(int fd);
2.3 read
ssize_t read(int fd, void *buf, size_t count);
- fd:文件描述符
- buf:将读到的内容放到buf这个缓冲区当中
- count:表示最大能够读多少字节,和buf的大小有关,需要在buf当中预留一个‘\0’的位置
- 返回值:
>0:读到的字节数量
-1:读失败
测试如下:
我们现在1.txt文件中写入一些内容,如下图所示:
我们将1.txt文件中的内容读入到buf中,然后打印出读到的内容和read的返回值
2.4 write
ssize_t write(int fd, const void *buf, size_t count);
- fd:文件描述符
- buf:写到文件当中的内容
- count:写入的字节数量
- 返回值:
>0:表示写入文件真实的字节数量
-1:写入失败
测试如下:
如下图所示使用cat命令我们可以看到我们已经将buf中的内容写入到1.txt文件中
2.5 lseek
off_t lseek(int fd, off_t offset, int whence);
- fd:文件描述符
- offset:偏移量
- whence:
SEEK_SET:文件的头部
SEEK_CUR:当前文件流指针的位置
SEEK_END:文件的尾部
测试如下图所示:
在2.4中我们测试的write虽然已经写入到文件中,但是,不能读出任何内容,原因和fseek处所说的类似,因为文件描述符会发生偏移,当我们写完内容后文件描述符会指向,最后一个字节的下一个位置,而此时再读取文件内容,会从文件描述符向后读取,而我们只需让文件描述符指向文件的头部即可读出内容