02Linux的标准IO

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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值