一看就会的Linux操作系统IO进程

什么是io

        io接口,又称为输入输出接口,是信息处理系统与外部世界之间的通信,输入时系统接受的信号或者数据,输出就是从其发送的信号或数据。

        input:通过终端向程序中输入数据;

        output:程序的结果通过终端(显示屏等)输出;

io的种类

文件io->系统调用

         系统调用就是操作系统提给应用程序(编程人员)使用的接口,可以理解其为一种可供应用程序调用的 '特殊函数',应用程序可以发出系统调用来获操作服务。从要从用户空间到内核空间就发生一次系统调用。

         系统调用的特点:1.系统调用的接口不同意,依赖于内核,不保证移植性

                                             2.系统调用没有缓冲区,效率比较低。

标准io->库函数

        库函数(AANSI C)是由文件io封装而来的,通过缓冲区机制减少系统调用,

        库函数=系统调用+缓冲区;库函数具有缓冲区,所以效率比系统调用更高。

缓冲区

        缓冲区:就是暂存输入(输出)的数据,等待缓冲区刷新,在一同输入(输出)到内核空间。

        缓冲区的种类和大小:

                全缓存:和文件相关的缓冲区就是全缓存(4096字节)4K;例如;fd;

                行缓存:和终端相关的缓冲区就是行缓存 (1024字节)1K;例如:stdin 、stdout

                不缓存:标准出错没有缓冲区 0 ;例如:stderr(标准出错)

       

缓冲区的刷新时机:

        行缓存的刷新时机:

                1.遇到换行符(\n)

                2.输入输出切换时

                3.程序运行结束时

                4.关闭文件

                5.缓存区存储满时

                6.使用fflush主动刷新缓冲区

        全缓存的刷新时机:

                1.输入输出切换时

                2.程序运行结束时

                3.关闭文件

                4.缓存区存储满时

                5.使用fflush主动刷新缓冲区

标准io的API函数

        在介绍标准io的API函数之前,先说一下FILE类型,FILE类型本质是一个结构体,这个结构体中记录所i有关于文件的信息,以后对文件的操作通过FILE*来完成。

        在打开文件的时候,会返回一个FILE*的指针(文明)

        FILE *fp 是声明,声明fp是指针,用来指向FILE类型的对象。

fopen ->使用标准io打开文件,

#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
功能:使用标准IO打开文件
参数:
   @pathname: 路径/文件名 "./hello.txt"
   @mode:打开文件的方式 "r" "r+"
    r:以只读的方式打开文件,将文件中的光标定位在文件的开头
    r+:以读写的方式打开文件,将文件中的光标定位在文件的开头
    w:以只写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空,将光标定位在开头 
    w+:以读写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空,将光标定位在开头  
    a:以追加(结尾写)的方式打开文件,如果文件不存在就创建文件,将光标定位在文件的结尾
    a+:以读和追加(结尾写)的方式打开文件,如果文件不存在就创建文件,如果读从开头读,写在文件的结尾写
返回值:成功返回文件指针,失败返回NULL,置位错误码

 fopen实例

#include <stdio.h>
int main(int magc,const char*argv[])
{
    //定义文件指针
    FILE* fd;

    //以只读方式打开文件
    fd = fopen("./hello.txt","r");
    if(NULL == fd)
    {
        printf("fopen error");
        return -1;
    }
    return 0;
}

fclose->关闭文件

int fclose(FILE *stream);
功能:关闭文件
参数:
    &stream:文件指针
返回值:
    成功返回0,失败返回(end of file),并置位错误码。

fclose实例

#include <stdio.h>
int main(int magv,const char*argv[])
{
    //定义文件指针
    FILE * fd;

    //以只写方式打开文件
    fd = fopen("./hello.txt","w")
    if(NULL == fd)
    {
        printf("fopen error");     
    }
    
    //关闭文件
    fclose(fd);
    return 0;
}

  关于错误码的问题

        在文件io和标准相关接口被调用时,如果出错了,操作系统会给程序返回错误码。

        我们在应用层使用fope打开文件的时候,底层的sys——open函数会被调用,如果fopen打开文件失败了,就会给上上层返回错误码,并将错误码的值赋值给errno变量,同时也会使fopen的返回值置为NULL。系统中一共有4K个错误码。

errno->错误码变量

#include <stdio.h
#include <errno.h>
//errno的头文件为<errno.h>
int main(int argc,const char* argv[])
{
    //FILE *fd;
    if(NULL == (fp=fopen("./hello.txt","w")
    {
        printf("fopen file error");
        //打印错误码
        printf("errno = %d\n",errno);
        return -1;
    }
    return 0;
}

 strerror->将错误信息码转为错位信息的函数strerror

#include <string.h>
char*strerror(int errnum);
功能:将错误码转为错误码对应错误信息
参数:
    @errnum:错误码(errno)
返回值:错误信息的字符串首地址

strerror实例

#include <stdio.h>
#incluse <errno.h>
#include <string.h>
int main(int argc,const char* argv[])
{
    FILE *fd;
    if(NULL == (fd = fopen("./hello.txt","a"))) //以追加方式打开文件
    {
        printf("fopen file error");
        printf("errno = %d\n",errno);
        //打印错误信息
        printf("strerror = %s\n",strerror(errno));
        return -1;
    }
    return 0;
}

perror->直接将将错误信息打印到终端(常用)

void perror("const char *s")
功能:将错误信息打印到终端
参数:
    @s:附加信息字符串
返回值:无

perror实例

#include <stdio.h>

int main(int argc, const char* argv[])
{
    FILE* fp;

    if ((fp = fopen("./hello.txt", "r")) == NULL)
    {
        //打印错误信息到终端
        perror("fopen file error");
        return -1;
    }

    return 0;
}

fgetc/fputc-> 像文件中读取/写入一个字符 

#include <stdio.h>
//fputc像文件中写入字符串
int fputc(int c, FILE *stream);
功能:向文件中写入字符
参数:
    @c:字符的ascii
    @stream:文件指针
返回值:成功返回字符ascii值,失败返回EOF(-1)


//fgetc从文件中读取一个字符
int fgetc(FILE *stream);
功能:从文件中读取字符
参数:
    @stream:文件指针
返回值:成功读取到的字符的ascii,读取到文件结尾或者出错,返回EOF(-1)

fgetc/fputc实例(使用fgetc/fputc使用文件拷贝)

#include <stdio.h>

int main(int argc, const char* argv[])
{
    FILE *fp1, *fp2;
    int ch;
    // 1.校验命令行参数的个数
    if (argc != 3) {
        printf("input error,try again\n");
        printf("usage: ./a.out srcfile destfile\n");
        return -1;
    }
    // 2.只读方式打开源文件,以只写方式打开目标文件
    if ((fp1 = fopen(argv[1], "r")) == NULL) {
        perror("fopen src error");
        return -1;
    }
    if ((fp2 = fopen(argv[2], "w")) == NULL) {
        perror("fopen dest error");
        return -1;
    }

    // 3.循环拷贝
    while ((ch = fgetc(fp1)) != EOF) {
        fputc(ch,fp2);
    }

    // 4.关闭文件
    fclose(fp1);
    fclose(fp2);
    return 0;

fgets/fputs->向对应的文件中获取/写入字符串

//fgts向对应文件中获取size-1个字符,获取的字符串自动加上'\0'
char *fgets(char *s, int size, FILE *stream);
功能:从stream对应的文件中最多读取size-1个字符到s中
    读停止:当遇到EOF或者换行符时候会停止,如果是换行符停止的,它会将换换行符存储到s中
    s的结束:在s存储的最后一个字符之后通过添加'\0'的形式表示结束
    s=0123456789'\n''\0'  size=100  文件第一行10个字符
    s=01234'\0'           size=6    文件第一行10个字符 
参数:
    @s:用于存储读取到的字符串的首地址
 @size:读取字符串中字符的个数
    @stream:文件指针
返回值:成功返回s,失败返回NULL

//fputs向对应文件中写入字符串
int fputs(const char *s, FILE *stream);
功能:将s中的内容写入到stream对应的文件中(不包含'\0')
参数:
    @s:被写字符串的首地址
 @stream:文件指针
返回值:成功返回大于0的值,失败返回EOF

fgets/fputs实例(使用fgets/fputs实现文件拷贝)

#include <stdio.h>

int main(int argc, const char* argv[])
{
    FILE *fp1, *fp2;
    char buf[20] = {0};
    // 1.校验命令行参数的个数
    if (argc != 3) {
        fputs("input error,try again\n",stderr);
        fputs("usage: ./a.out srcfile destfile\n",stderr);
        return -1;
    }
    // 2.只读方式打开源文件,以只写方式打开目标文件
    if ((fp1 = fopen(argv[1], "r")) == NULL) {
        perror("fopen src error");
        return -1;
    }
    if ((fp2 = fopen(argv[2], "w")) == NULL) {
        perror("fopen dest error");
        return -1;
    }

    // 3.循环拷贝 fgets成功返回buf(非0就会进入while),
    //失败返回NULL(void *)0,假退出循环
    while (fgets(buf,sizeof(buf),fp1)) {
        fputs(buf,fp2);
    }

    // 4.关闭文件
    fclose(fp1);
    fclose(fp2);
    return 0;
}

下课!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值