Linux 文件IO中的标准IO
----------------------------------------标准IO-------------------------------------------
由标准C库提供函数接口,特点就是特别丰富
有提供缓冲区,对于海量数据的处理效率较高
编程的过程中建议使用标准IO 来实现, 除非不能用
标准 C 库是最常用的第三方库,而标准 IO 就是标准 C 库中的一部分接口,这一部分
接口实际上是系统 IO 的封装,他提供了更加丰富的读写方式,比如可以按格式读写、按
ASCII 码字符读写、按二进制读写、按行读写、按数据块读写等等,还可以提供数据读写
缓冲功能,极大提高程序读写效率。
标准IO引入了流的概念,表示为FILE,FILE实际上包含了为管理流所需要的所有信息:标准I/O对每个I/O流自动进行缓存管理,它提供了三种类型的缓存:
①:全缓存。当填满标准I/O缓存后才执行I/O操作。磁盘上的文件通常是全缓存的。
②:行缓存。当输入输出遇到新行符或缓存满时,才由标准I/O库执行实际I/O操作。stdin、stdout通常是行缓存的。
③:无缓存。相当于read、write了。stderr通常是无缓存的,因为它必须尽快输出。
一、打开文件:fopen()
头文件:#include <stdio.h>
定义函数
FILE * fopen(const char * path, const char * mode);
参数分析:
path:需要打开的文件名字 路径+文件名(如果没有写路径,就默认为当前路径)
mode:打开文件的方式
r-----打开只读文件, 该文件必须存在
r+-----打开可读写的文件, 该文件必须存在
w-----打开只写文件, 若文件存在则文件长度清零, 即该文件内容会消失. 若文件不存在则建立该文件
w+-----打开可读写文件, 若文件存在则文件长度清零, 即该文件内容会消失若文件不存在则建立该文件
a-----以附加的方式打开只写文件. 若文件不存在, 则会建立该文件, 如果文件存在, 写入的数据会被追加到文件的末尾
a+-----以附加方式打开可读写的文件. 若文件不存在, 则会建立该文件, 如果文件存在, 写入的数据会被追加到文件的末尾
返回值:
成功 返回一个文件指针(FILE *类型的)
失败 返回NULL
-------------------------------全缓存的方式读写文件-------------------------------
二、写入文件:fwrite()
头文件:#include <stdio.h>
定义函数
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
参数分析:
ptr:需要打开的文件名字 路径+文件名(如果没有写路径,就默认为当前路径)
size:每次写入文件的字节大小
nmemb:每次写入文件的字节数
stream:需要写入的文件的文件指针
返回值:
成功 返回实际写入文件的nmemb的数目
失败 返回小于nmemb的数目
三、读文件:fread()
头文件:#include <stdio.h>
定义函数
size_t fread(void *ptr, size size, size_t nmemb, FILE *stream);
参数分析:
ptr:需要打开的文件名字 路径+文件名(如果没有写路径,就默认为当前路径)
size:每次读出字节的大小
nmemb:每次读出的字节数
stream:需要读的文件的文件指针
返回值:
成功 返回实际读到的nmemb的数目
失败 返回小于nmemb的数目
四、关闭文件:fclose()
头文件:#include <stdio.h>
定义函数
int fclose(FILE *stream);
参数分析:
stream:需要关闭的文件的文件指针
操作练习(全缓存): 文件的 写入和读取
打开一个文件,对文件写入数据并且读取出来
#include "stdio.h"
int main(void)
{
FILE *fd;
char buf[] = "123456789qwrtyui12";//写入文件的字符缓冲区
char buf1[] = {0};//读出文件的字符缓冲区
int num = 1;
int i = 0;
fd = fopen("1.c", "r+");//用可写可读的方式打开文件
if(fd == NULL)
{
printf("打开失败");
return -1;
}
printf("打开成功");
while(1)
{
if(buf[i] != '\0')
{
num = fwrite(&buf[i], sizeof(char), 1, fd);//每次一个字节的数据大小写入文件
i++;
}
else
{
printf("文件写入成功\n");
fclose(fd);//关闭打开的文件
break;
}
}
i = 0;
//若是用fseek函数把文件指针移动到投钱头部,可以直接进行读取,不需要关闭文件
// fseek(fd, 0, SEEK_SET);
fd = fopen("1.c", "r+");//重新打开文件
if(fd == NULL)
{
printf("打开失败");
return -1;
}
printf("打开成功");
while(1)
{
if(buf[i] != '\0')
{
num = fread(&buf[i], sizeof(char), 1, fd);//每次读出一个字节的数据
i++;
}
else
{
printf("文件读取成功:%s\n", buf);
fclose(fd);//关闭打开的文件
break;
}
}
}
四、移动文件流的读写位置:fseek()
头文件: #include <unistd.h>
定义函数:
int fseek(FILE *stream, long offset, int whence);
参数分析:
stream:需要操作的文件的文件指针
offset:需要移动的偏移量
whence:偏移的模式
SEEK_SET 从距文件开头 offset 位移量为新的读写位置
SEEK_CUR 以目前的读写位置往后增加offset 个位移量
SEEK_END 将读写位置指向文件尾后再增加 offset 个位移量
返回值:
当调用成功时则返回 0
若有错误则返回-1
五、取得文件流的读取位置:ftell()
头文件: #include <unistd.h>
定义函数:
long ftell(FILE *stream);
参数分析:
stream:stream --> 需要读取位置的文件指针
返回值:
成功时返回当前读写的位置
失败返回-1
-------------------------------行缓存的方式读写文件-------------------------------
六、按字节读取/写入文本的内容
读取:
定义函数:
int getchar() // 从标准输入文件中读取一个字节
int fgetc(FILE * stream) ; // 函数
int getc(FILE * stream) ; // 宏定义
参数分析:
stream:stream --> 需要读取位置的文件指针
返回值:
成功:返回一个字符的AScii码
失败:返回EOF标志 又可能是到了文件末尾,也有可能是读取失败
写入:
定义函数:
int putchar (int c); // 把一个字符写入到标准输出文件中
int fputc(int c, FILE * stream); // 把 整型c转为字符并写入到 stream 所对应文件中
int putc(int c, FILE * stream); // 宏定义
参数分析:
stream:stream --> 需要写入位置的文件指针
返回值:
成功:返回写入成功的字符
失败:返回EOF标志
七、按行进行读取/写入到文件中
读取:
定义函数:
char * fgets(char * s, int size, FILE * stream);
char * gets(char *s); // 从标准输入中读取一个字符串
参数分析:
s:存放读取到数据的缓存区
size:最大读取字符数据的大小,即缓存区的大小
stream:stream --> 需要读取文件的文件指针
返回值:
成功:返回一个char * s的指针
失败:返回空指针(NULL)
注意:fgets 读取文件时直到出现换行字符、读到文件尾或是已读了 size-1 个字符为止, 最后会加上NULL 作为字符串结束
写入:
定义函数:
int fputs(const char * s, FILE * stream); // 把s所指向则内存写入到stream 所指向的文件中
int puts(const char *s); // 把一个字符串输出到标准输出文件中
参数分析:
s:写入文件的数据的缓存区
stream:stream --> 需要写入文件的文件指针
返回值:
成功:返回写入文件的字节数
失败:返回EOF
八、如何判断返回EOF时是出错还是到达文件末尾
定义函数:
int feof(FILE *stream);//检查文件是否读到了文件尾
参数分析:
stream:stream --> 需要判断的文件的文件指针
返回值:
达到了文件尾就返回非零值
操作练习(行缓存): 实现 文件的拷贝
#include "stdio.h"
int main()
{
FILE *w_fd;
FILE *r_fd;
char r_buf[128] = {0};
char w_buf[128] = {0};
//使用a+(打开文件,若文件不存在则创建新文件,存在则在文件最后追加数据)的方式打开文件
r_fd = fopen("1.c", "a+");
if(r_fd == NULL)
{
printf("打开文件1失败\n");
return -1;
}
printf("打开文件1成功\n");
w_fd = fopen("2.c", "a+");
if(w_fd == NULL)
{
printf("打开文件2失败\n");
return -1;
}
printf("打开文件2成功\n");
//先把文件1的数据读取出来,再放入文件2中
while(fgets(r_buf, sizeof(r_buf), r_fd) != NULL)
{
printf("%s\n", r_buf);
if(fputs(r_buf, w_fd) == EOF)
{
printf("写入数据失败\n");
return -1;
}
}
//关闭文件
fclose(r_fd);
fclose(w_fd);
return 0;
}