linux 标准I/O函数详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 标准I/O函数详解相关的知识,希望对你有一定的参考价值。

1、I/O操作是系统的基础。

    I/O 表示的input【输入】和output【输出】 。I/O操作是系统实现的基础。如果没有I/O操作,所以有的系统文件将无法存储,更谈不上处理与分析,系统运行的结果也不为用户所见。


2、系统IO与标准IO的区别

    I/O 分为标准IO 和系统IO 。标准io称为stdio,系统IO又称为文件IO。系统IO是内核提供给用户处理IO操作的接口。例如:标准C是不能处理输入输出问题的。必须借助于内核提供的接口实现对program的输入输出处理。标准I/O 是在系统IO的基础上进行的二次封装。以屏蔽不同体系结构之间的差异,增加程序的可移植性。


技术分享


        从上图可以发现:标准I/O是基于系统IO实现的。fopen是基于open方法实现,fclose是基于close实现的。fgetc,fputc,fgets,fputs,fread,fwrite,是基于read和write方法是实现,fseek,ftell,rewind是基于lseek方法实现。

        贯穿标准IO的全过程,有一个重要的结构体:FILE,贯穿系统IO的全过程,有一个重要的整形变量:int fd(其中fd表示:file descriptot,文件描述符)。二者的关系如何?

      技术分享

        

3、标准I/O相关函数使用:

  3.1 fopen函数:

    用法:FILE *fopen(const char *path, const char *mode);

    参数:const  char *path 打开指定路径下的文件。const修饰为了增强程序安全性【调用的参数不能修改】 const char *mode 表示文件的打开方式:

    

mode含义
r只读方式打开,文件位置指针位于文件的起始处【文件必须事先存在,否则出错】
r+只读写方式打开,文件位置指针位于文件的起始处【文件必须事先存在,否则出错】
w有则清空,无则创建。文件位置指针位于文件的起始处
w+有则清空,无则创建。文件位置指针位于文件的起始处
a以附加的方式打开,文件位置指针位于未见末尾处
a+以读或附加的方式打开,文件位置指针取决于用户的操作方式。读则在起始处,附加则在末尾处。

    返回值:打开成功则返回FILE 类型指针,失败则返回空指针,并写入errno值。

    用法举例:

    

    #include <stdio.h>    
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    int main ()
    {
    FILE *f = NULL;
    f = fopen("tmp","w");
    if(f == NULL)
    {
    //fprintf(stderr,"fopen() failed ! errno = %d\n",errno);
    //查看出错原因。去:/usr/include/asm-generic/errno-bash.h
    //使用perro函数
    //perror("fopen()");
    //另外一个好用的函数
    fprintf(stderr,"fopen():%s\n",strerror(errno));
    exit(1);
    }
    puts("ok");
    fclose(f);
    //exit(0);
    }


3.2 fclose:

    功能:关闭打开的文件指针,并且刷新缓存。

    用法:int fclose(FILE *fp);

    参数:FILE *fp 打开的文件指针。

    返回值:成功返回0,如果不成功返回EOF,并且设置errno。


3.3、fgetc fputc 

    功能:

        fgetc:从流中读入下一个字符,【字符读入以整形返回】。

        fputc:输出一个字符

    用法:

        int fgetc(FILE *stream);

        int fputc(int c, FILE *stream);

    返回值:

        fgetc(),  getc() and getchar() return the character read as an unsigned char cast to an

       int or EOF on end of file or error.    

    fputc(),  putc() and putchar() return the character written as an unsigned char cast to

       an int or EOF on error

    注意点:fgetc的返回值要用一个int接收,不能定义为char型。

        EOF是 End Of File 的缩写。在C语言中,它是在标准库中定义的一个宏。多数人认为文件中有一个EOF,用于表示文件的结尾。但这个观点实际上是错误的,在文件所包含的数据中,并没有什么文件结束符。对getc 而言,如果不能从文件中读取,则返回一个整数-1,这就是所谓的EOF。返回 EOF 无非是出现了两种情况,一是文件已经读完;;二是文件读取出错,反正是读不下去了。

        用法举例:用fgetc 和fputc实现文件复制的功能。

        

#include <stdio.h>

#include <stdlib.h>

int main (int argc ,char *argv[])

{

FILE *fs,*fd;

int ch;

if(argc < 3)

{

fprintf(stderr,"useage:%s<src_filename des_filename>",argv[0]);

exit(1);

}

fs = fopen(argv[1],"r");

if(fs == NULL)

{

perror("fopen()");

exit(1);

}

fd = fopen(argv[2],"w");

if(fd == NULL)

{

fclose(fs);          //如果此时程序中断,应该释放打开源

perror("fopen()");

exit(1);

}

while(1)

{

ch = fgetc(fs);

if(ch == EOF)

{

break;

}

fputc(ch,fd);

}

fclose(fd);

fclose(fs);

3.3、fputs 和fgets

        功能:以字符串的形式读取和写入文件。

        用法:

          char *fgets(char *s, int size, FILE *stream);  

          int fputs(const char *s, FILE *stream);

        返回值:fgets会把从*stream中读取的size个字节放入到*s,char* 表示回写。fputs 返回值是一个整形,成功为非负值,失败,返回EOF

        用法举例:用fgets和fputs实现文件复制的功能。        

#include <stdio.h>

#include <stdlib.h>

#define BUFSIZE 1024

int main (int argc ,char **argv)

{

    if(argc < 2)

    {

        fprintf(stderr,"Usage....\n");

        exit(1);

    }

    char buf[BUFSIZE];

    FILE *fsp,*fdp;


    fsp = fopen(argv[1],"r");

    if(fsp == NULL)

    {

        perror("fopen()");

        exit(1);

    }

    fdp = fopen(argv[2],"w");

    if(fdp == NULL)

    {

        fclose(fsp);

        perror("fopen()");

        exit(1);

    }

    while(fgets(buf,BUFSIZE,fsp) != NULL)

    {

        fputs(buf,fdp);

    }

    exit(0);

}


3.4 fread 和 fwrite

    作用:二进制流的输入输出

    用法:        

        size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);


        size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

    注意:size是每一个块的大小,nmemb是块的个数。

    返回值:读取或写入的字节个数【正确】。读完或出错返回0值

    用法举例:用fread和fwrite实现文件复制的功能。

  1 #include <stdio.h>

  2 #include <stdlib.h>

  3 #define BUFSIZE 1024

  4 int main (int argc ,char **argv)

  5 {

  6 

  7     if(argc < 3)

  8     {   

  9         fprintf(stderr,"Usage....\n");

 10         exit(1);

 11     }

 12     FILE *fsp,*fdp;

 13     char buf[BUFSIZE];

 14     int n,res;

 15     fsp = fopen(argv[1], "r");

 16     if(fsp == NULL)

 17     {

 18         perror("fopen()");

 19         exit(1);

 20     }

 21     fdp = fopen(argv[2],"w");

 22     if(fdp == NULL)

 23     {

 24         fclose(fsp);

 25         perror("fopen()");

 26         exit(1);

 27     }

 28     while ((n = fread(buf,1,BUFSIZE,fsp)) > 0 )

 29     {

 30         res = fwrite(buf,1,n,fdp);

 31         n = n - res;                            //全部读取

 32         if(n > 0)

 33         {

 34             while(res > 0)

 35             {

 36                 res = fwrite(buf,1,n,fdp);

 37                 n = n -res;

 38             }

 39         }

 40     }

 41     exit(0);

 42 }

本文出自 “hylinux” 博客,请务必保留此出处http://hongyilinux.blog.51cto.com/8030513/1746199

以上是关于linux 标准I/O函数详解的主要内容,如果未能解决你的问题,请参考以下文章

Linux 标准 I/O 库

Linux系统学习笔记:文件I/O

零拷贝原理详解

零拷贝原理详解

零拷贝原理详解

Linux系统I/O模型详解