浅析文件IO和标准IO

目录

一.标准IO和文件IO区别

二.标准IO的函数

三.关于错误码的问题

四.关于缓冲区刷新机制的问题

6.当文件缓冲区大小超过1024时会刷新缓冲区,多余的的会再次放到缓冲区里


一.标准IO和文件IO区别

1.标准输入:从终端向程序中写入

2.标准输出:程序执行的结果通过终端显示

3.IO的种类:文件IO:系统调用    标准IO:系统调用+缓冲区

4.系统调用:从用户空间进入到内核空间的一个过程,操作系统不同,接口也就不同,效率低,只要系统发生调用,就要调用一次内核

5.库函数:相当于系统调用+缓冲区实现的,可移植性较强,几乎在所有的操作系统都能用,效率高

6.FILE结构体:只要打开一个文件,就会生成一个FILE结构体,可以通过追代码查找到FILE结构体里边的内容

 _IO_buf_base:就是缓冲区的起始地址

_IO_buf_end:就是缓冲区的结束地址

7.追代码工具: 先创建一个索引ctags -R 会生成一个tags索引文件   当文件未打开时通过 vi -t (变量或者函数名)    打开文件(文件已打开)后按ctrl +]   回退按ctrl+t      

二.标准IO的函数

1.fopen(const char*pathname,const char*mode):

功能:打开一个文件

参数:  pathname:文件的路径及文件名

mode:权限

r:以只读的方式打开文件,将光标定位到开头

r+:以读写的方式打开文件,将光标定位到开头  (r和r+都是只能打开已经有的文件)

w:以只写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空文件,将光标定位到开头

w+:以读写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空文件,将光标定位到开头

a:以只写的方式打开文件,如果文件不存在就创建文件,如果文件存在就将光标定位到结尾

a+:以读写的方式打开文件,如果文件不存在就创建文件,如果文件存在写在结尾写,读从开头读

返回值:成功返回FILE结构体的指针,失败返回NULL置位错误码

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;//定义一个FILE结构体类型的指针
    //fp=fopen("./hello.txt","r");//以只读的方式打开当前路径下的hello.txt文件
    if((fp=fopen(argv[1],"w"))==NULL){//以只写的方式打开./a.out 后面跟着的文件,如果文件不存在 
                                        就创建,存在就清空文件
        printf("open file error\n");
        return -1;
    }
    printf("open file success\n");
    return 0;
}

2.fclose(FILE *stream):

功能:关闭一个文件

参数:  stream:文件指针

返回值:成功返回0,失败返回EOF(-1)置位错误码

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;//定义一个FILE结构体类型的指针
    //打开一个文件默认打开stdin,stdout,stderr
    //fp=fopen("./hello.txt","r");//以只读的方式打开当前路径下的hello.txt文件
    if((fp=fopen(argv[1],"w"))==NULL){
        printf("open file error\n");
        return -1;
    }//以只写的方式打开./a.out 后面跟着的文件,如果文件不存在就创建,存在就清空文件
    //关闭一个文件
    printf("open file success\n");
    if(fclose(fp)==-1){
        printf("close file error\n");
        return -1;
    }
    //不过一般情况下关闭文件都会成功,直接关闭就行,无需判断,直接fclose(fp)会将打开的文件全部关闭
    fclose(stdin);
    fclose(stdout);
    fclose(stderr);
    return 0;
}

3.fgetc(FILE *stream):

功能:从文件中读取一个字符(也可以从终端读一个字符到文件中)

参数:  stream:文件指针

返回值:成功返回0,失败返回EOF(-1)置位错误码

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;
    if((fp=fopen("./hello.txt","w"))==NULL){
        printf("open file error\n");
        return -1;
    }
    printf("open file success\n");
    printf("fgetc=%c\n",fgetc(fp));//操作fp,其实就是操作打开的文件,这里是从文件中读取一个字        符,在终端上打印出来
    fclose(fp);
    return 0;
}

4.fputc(FILE *stream):

功能:向文件中写入一个字符(也可以写一个字符到终端上)

参数:  stream:文件指针

返回值:成功返回0,失败返回EOF(-1)置位错误码

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;
    if((fp=fopen("./hello.txt","w"))==NULL){
        printf("open file error\n");
        return -1;
    }
    printf("open file success\n");
    //每次只能写一个字符
    fputc("h",fp);
    fputc("e",fp);
    fputc("l",fp);
    fputc("l",fp);
    fputc("o",fp);

    fclose(fp);
    return 0;
}

三.关于错误码的问题

应用层的fopen函数会调用底层的sys_open函数,sys_open执行失败时会将错误码传给errno的变量,通过这个变量获取到底层的错误

  1. 直接打印错误码,不能打印错误信息
  2. #include <stdio.h>
    #include <errno.h>
    extern int errno;
    
    int main(int argc, char const *argv[])
    {
        FILE *fp;
        if((fp=fopen("./hello.txt","r"))==NULL){
            printf("errno=%d\n",errno);//当文件以只读形式打开,但是文件不存在时,就会打印错误码
            printf("open file error\n");
            return -1;
        }
        printf("open file success\n");
        fclose(fp);
        return 0;
    }
  3. 调用strerror函数通过错误码转换出来打印错误信息

              Char *strerror(int errnum):

              功能:根据错误码转换出错误信息

              参数:  errnum:错误码

              返回值:错误信息

#include <stdio.h>
#include <errno.h>
#include <string.h>
extern int errno;

int main(int argc, char const *argv[])
{
    FILE *fp;
    if((fp=fopen("./hello.txt","r"))==NULL){
        printf("errno=%d\n",errno);//当文件以只读形式打开,但是文件不存在时,就会打印错误码
        printf("strerror(errno)=%s\n",strerror(errno));//打印出来错误码对应的错误信息
        printf("open file error\n");
        return -1;
    }
    printf("open file success\n");
    fclose(fp);
    return 0;
}

        4.调用perror函数直接打印错误信息

              void  perror(const char *s):

             功能:直接打印错误信息(自动加上\n)

            参数:  s:用户附加的错误信息

            返回值:无

#include <stdio.h>

int main(int argc, char const *argv[])
{
    FILE *fp;
    if((fp=fopen("./hello.txt","r"))==NULL){
        perror("open file");//直接打印出来错误信息,括号里边是附加信息
        printf("open file error\n");
        return -1;
    }
    printf("open file success\n");
    fclose(fp);
    return 0;
}

四.关于缓冲区刷新机制的问题

1.fflush(FILE *stream):

功能:主动刷新缓冲区

参数:  stream:文件指针

返回值:成功返回0,失败返回EOF(-1)置位错误码

2.缓冲区机制刷新问题

全缓存  操作的是文件

1.程序结束的时候会刷新

2.文件关闭的时候会刷新

3.标准输入和标准输出发生切换时会刷新(先写在读)

4.调用fflush会刷新

5.当文件缓冲区大小超过4096时会刷新缓冲区

行缓存:stdin  stdout  和终端交互,缓冲区会等待,需要刷新才能显示,缓冲区大小是1024

1.遇到’\n’会刷新缓冲区

2.程序结束的时候会刷新

3.文件关闭的时候会刷新

4.标准输入和标准输出发生切换时会刷新(先写在读)

5.调用fflush会刷新

6.当文件缓冲区大小超过1024时会刷新缓冲区,多余的字符会再次放到缓冲区里

不缓存:stderr  没有缓冲区会直接输出,缓冲区大小是0

3.行缓冲区大小主要是通过stdin(或stdout)->_IO_buf_end  -   stdin(或stdout)->_IO_buf_base得到的

全缓冲区大小主要是通过fp->_IO_buf_end  -   fp->_IO_buf_base得到的

  1. 不缓冲区大小主要是通过stderr->_IO_buf_end  -   stderr->_IO_buf_base得到的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值