1. 文件读写函数简介
文件I/O是C语言的一项基本操作,主要包括从文件中读取数据和向文件中写入数据两种操作。C语言提供了一系列的标准库函数和系统调用函数来完成这些操作。
标准库函数常用于高级应用程序,可以实现对文件的高级操作,比如文件复制、读取/写入文本等等。而系统调用函数则直接操作操作系统的文件系统,性能更高,可以完成对文件的原始操作,比如创建/删除文件、读取/写入二进制文件等。
2. 标准库文件读写函数
2.1. fopen
打开文件的函数,语法为:
FILE *fopen(const char *filename, const char *mode);
其中filename为要打开的文件名,mode为打开文件的模式,常用的模式包括:
"r": 以只读方式打开文件。
"w": 以只写方式打开文件,如果文件已存在则清空文件内容,如果文件不存在则创建一个新的文件。
"rb": 以只读二进制方式打开文件。
"wb": 以只写二进制方式打开文件,如果文件已存在则清空文件内容,如果文件不存在则创建一个新的文件。
fopen
函数返回一个指针,指向打开的文件。
2.2. fclose
关闭文件的函数,语法为:
int fclose(FILE *stream);
其中stream为要关闭的文件指针,fclose
函数返回0表示成功关闭文件,-1表示关闭失败。
2.3. fgetc
从文件中读取一个字符的函数,语法为:
int fgetc(FILE *stream);
其中stream为要读取的文件指针,fgetc
函数返回读取到的字符的ASCII码值,读取到文件末尾时返回EOF(-1)。
2.4. fputc
向文件中写入一个字符的函数,语法为:
int fputc(int c, FILE *stream);
其中c为要写入的字符的ASCII码值,stream为要写入的文件指针,fputc
函数返回写入的字符的ASCII码值。
2.5. fgets
从文件中读取一行字符串的函数,语法为:
char *fgets(char *s, int size, FILE *stream);
其中s为接收读取字符串的字符数组指针,size为接收读取字符串的字符数组大小,stream为要读取的文件指针,fgets
函数返回读取到的字符串的指针。
2.6. fputs
向文件中写入一行字符串的函数,语法为:
int fputs(const char *s, FILE *stream);
其中s为要写入的字符串,stream为要写入的文件指针,fputs
函数返回写入成功的字符数量。
3. 系统调用文件读写函数
3.1. 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_CREAT: 如果文件不存在则创建一个新的文件。
open
函数返回一个文件描述符,该文件描述符用于后续文件操作。
3.2. close
关闭文件的函数,语法为:
int close(int fd);
其中fd为要关闭的文件描述符,close
函数返回0表示成功关闭文件,-1表示关闭失败。
3.3. read
从文件中读取数据的函数,语法为:
ssize_t read(int fd, void *buf, size_t count);
其中fd为要读取的文件描述符,buf为接收读取数据的缓冲区指针,count为要读取的字节数,read
函数返回实际读取的字节数,读取到文件末尾时返回0。
3.4. write
向文件中写入数据的函数,语法为:
ssize_t write(int fd, const void *buf, size_t count);
其中fd为要写入的文件描述符,buf为要写入的数据缓冲区指针,count为要写入的字节数,write
函数返回实际写入的字节数。
3.5. lseek
移动文件指针的函数,语法为:
off_t lseek(int fd, off_t offset, int whence);
其中fd为要移动文件指针的文件描述符,offset为要移动的字节数,whence为移动基准,可选的值包括:
SEEK_SET: 从文件开头开始移动。
SEEK_CUR: 从当前位置开始移动。
SEEK_END: 从文件末尾开始移动。
lseek
函数返回移动后的文件指针位置。
4. 文件操作示例
下面是一个使用标准库函数和系统调用函数进行文件读写的示例:
4.1. 标准库函数示例
#include <stdio.h>
int main()
{
FILE *fp;
char ch;
// 打开文件
fp = fopen("test.txt", "r");
if (fp == NULL)
{
printf("File not exists\n");
return -1;
}
// 读取文件
while ((ch = fgetc(fp)) != EOF)
{
printf("%c", ch);
}
// 关闭文件
fclose(fp);
// 写入文件
fp = fopen("test.txt", "a");
if (fp == NULL)
{
printf("File not exists\n");
return -1;
}
fprintf(fp, "Hello, world!");
fclose(fp);
return 0;
}
运行该程序后会首先打开test.txt文件进行读取,然后将字符串"Hello, world!"写入文件末尾。
4.2. 系统调用函数示例
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd;
char buf[1024];
// 打开文件
fd = open("test.txt", O_RDONLY);
if (fd == -1)
{
printf("File not exists\n");
return -1;
}
// 读取文件
read(fd, buf, sizeof(buf));
printf("%s", buf);
// 关闭文件
close(fd);
// 写入文件
fd = open("test.txt", O_WRONLY|O_APPEND);
if (fd == -1)
{
printf("File not exists\n");
return -1;
}
write(fd, "Hello, world!", sizeof("Hello, world!"));
close(fd);
return 0;
}
运行该程序后会首先打开test.txt文件进行读取,然后将字符串"Hello, world!"写入文件末尾。
5. 总结
文件I/O是C语言中常用的操作之一,开发者可以根据实际需要选择标准库函数或系统调用函数来完成文件读写操作。标准库函数常用于高级应用程序,可以实现对文件的高级操作,而系统调用函数直接操作操作系统的文件系统,性能更高,可以完成对文件的原始操作。