zoukankan      html  css  js  c++  java
  • 文件读写IO

    摘要:本文主要总结了以下有关文件读写的IO,系统调用与库函数。


    1.初级IO函数:close,creat,lseek,open,write


    文件描述符是一个整型数


    1.1close


    1.2int creat(const char * pathname, mode_t mode);

    int creat(const char * pathname, mode_t mode);
    函数功能:
    创建一个文件并以只写的方式打开。如果原来该文件存在,会将这个文件的长度截短为0。
    函数说明
    若函数执行成功则返回打开文件的描述符,出错返回-1并设置errno。(关于errno详见《UNIX环境高级编程》第一章第七节)
    参数pathname指向欲建立的文件路径字符串。creat()相当于使用下列的调用方式调用open()
    open(const char * pathname ,(O_CREAT|O_WRONLY|O_TRUNC));
    由于creat函数创建文件后是以只写的方式打开,因此局限性比较大,所以一般都用open函数来代替creat函数创建一个文件,这样创建后就能同时以读写的方式打开文件了。


    1.3off_t lseek(int fildes,off_t offset ,int whence)

    #include<sys/types.h>
    #include<unistd.h>

    定义函数

    off_t lseek(int fildes,off_t offset ,int whence);

    函数说明

    每一个已打开的文件都有一个读写位置,当打开文件时通常其读写位置是指向文件开头,若是以附加的方式打开文件(如O_APPEND),则读写位置会指向文件尾。当read()或write()时,读写位置会随之增加,lseek()便是用来控制该文件的读写位置。参数fildes 为已打开的文件描述词,参数offset 为根据参数whence来移动读写位置的位移数。
    Offset:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)。

    参数

    whence为下列其中一种:(SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2).
    SEEK_SET 将读写位置指向文件头后再增加offset个位移量。
    SEEK_CUR 以目前的读写位置往后增加offset个位移量。
    SEEK_END 将读写位置指向文件尾后再增加offset个位移量。
    当whence 值为SEEK_CUR 或SEEK_END时,参数offet允许负值的出现。
    下列是较特别的使用方式:
    1) 欲将读写位置移到文件开头时:
    lseek(int fildes,0,SEEK_SET);
    2) 欲将读写位置移到文件尾时:
    lseek(int fildes,0,SEEK_END);
    3) 想要取得目前文件位置时:
    lseek(int fildes,0,SEEK_CUR);

    返回值

    当调用成功时则返回目前的读写位置,也就是距离文件开头多少个字节。若有错误则返回-1,errno 会存放错误代码

    1.4int open(const char *pathname, int flags);
    作用:打开和创建文件。
    简述:
    #include <fcntl.h>

    intopen(const char *pathname, int flags, mode_t mode);
    返回值:成功则返回文件描述符,否则返回 -1
    对于open函数来说,第三个参数仅当创建新文件时(即 使用了O_CREAT 时)才使用,用于指定文件的访问权限位(access permission bits)。pathname 是待打开/创建文件的POSIX路径名(如/home/user/a.cpp);flags 用于指定文件的打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑位或逻辑构成。
    O_RDONLY 只读模式
    O_WRONLY 只写模式
    O_RDWR 读写模式

    1.5ssize_t write (int fd,const void * buf,size_t count);

    返回值:如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入errno中。

            0)非缓冲文件系统依赖于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件,但效率高、速度 快,由于ANSI标准不再包括非缓冲文件系统,因此建议大家最好不要选择它。

    1)关于系统调用

    read和write属于初级读写函数,也是系统调用;系统调用需要消耗大量时间。因为代码执行权会从用户转移到内核,执行内核代码是需要时间的。系统调用开销巨大,因为系统调用需要特殊的内存和堆栈环境,这些需要在系统调用之前建立好;系统调用之后又需要恢复这些环境。这种环境切换需要耗费大量时间。最好的方法就是建立缓冲区,一次读取大量数据,避免多次进行系统调用。我们可以用这个思想来改造前一篇中的who。

    2)系统调用的错误处理

    一般约定,系统调用open,write,lseek在出错时会返回值-1。另外,系统调用都有自己的错误集,以open为例,打开文件不存在,没有读的权限,打开文件太多等等。内核通过全局变量errno来确定错误类型,其中哦功能error.h中规定了一些错误的宏。


    2.标准IO函数


    2.1int fclose(FILE *stream);

    如果流成功关闭,fclose 返回 0,否则返回EOF(-1)


    2.2int feof(FILE *stream)

    feof(fp)有两个返回值:如果遇到文件结束,函数feof(fp)的值为非零值,否则为0。


    2.3int fgetc(FILE *stream);

    这个函数的返回值,是返回所读取的一个字节。如果读到文件末尾或者读取出错时返回EOF。


    2.4char *fgets(char *buf, int bufsize, FILE *stream)

    fopen从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋''),如果文件中的该行,不足bufsize个字符,则读完该行就结束。函数成功将返回buf,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。bufsize的作用是防止缓冲区溢出。


    2.5FILE * fopen(const char * path,const char * mode);

    文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno 中。

    r 以只读方式打开文件,该文件必须存在。
    r+ 以可读写方式打开文件,该文件必须存在。
    rb+ 读写打开一个二进制文件,允许读写数据
    rw+ 读写打开一个文本文件,允许读和写。
    w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
    w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。


    2.6int fputc (int n, File *fp)

    功能:输出一个字符到某个文件

    2.7size_t fread ( void   *buffer,  size_t size,  size_t count,  FILE *stream) ;

    size
    单个元素的大小,单位是字节
    返回值:
    实际读取的元素个数.如果返回值与count不相同,则可能文件结尾或发生错误.
    从ferror和feof获取错误信息或检测是否到达文件结尾.

    2.8int fseek(FILE *stream, long offset, int fromwhere);

    函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
    fseek函数和lseek函数类似,但lseek返回的是一个off_t数值,而fseek返回的是一个整型。


    2.9size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream)

    返回实际写入的数据项个数count。
    说明:写入到文件的哪里? 这个与文件的打开模式有关,如果是w+,则是从file pointer指向的地址开始写,替换掉之后的内容,文件的长度可以不变,stream的位置移动count个数;如果是a+,则从文件的末尾开始添加,文件长度加大。

    2.10int getc(FILE *stream);

    注意: 此函数被ISO C声明为一个宏,所以在用时不能将其做为函数指针传(有一些编译器将其以函数形式也给另说)。


    2.11getchar()

    从stdio流中读字符,相当于getc(stdin),它从标准输入里读取下一个字符


    2.12gets

    从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为null值,并由此来结束字符串。


    2.13int fputc(char ch,FILE*fp)

    putc()与fputc()等价。不同之处为:当putc函数被定义为宏时,它可能多次计算stream的值。


    2.14 int putchar(int ch);

    在标准输出上输出一个字符


    2.15int puts(char *string);

    功能:送一字符串到流stdout中

          缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用,当执行读文件的操作时,从磁盘文件将数据先读入内存“缓冲区”, 装满后再从内存“缓冲区”依此读入接收的变量。执行写文件的操作时,先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。由此可以看出,内存 “缓冲区”的大小,影响着实际操作外存的次数,内存“缓冲区”越大,则操作外存的次数就少,执行速度就快、效率高。一般来说,文件“缓冲区”的大小随机器 而定。


    3.格式化输出输出函数


    3.1printf


    3.2int fprintf(FILE *stream,char *format,[argument])

    功能:格式化输出到一个流/文件中;

    返回值:fprintf()的返回值是输出的字符数,发生错误时返回一个负值.


    3.3scanf


    3.4int fscanf(FILE *stream, char *format,[argument...]);

    功 能: 从一个流中执行格式化输入,fscanf遇到空格和换行时结束,注意空格时也结束。这与fgets有区别,fgets遇到空格不结束。


  • 相关阅读:
    扫描线算法
    [Baltic 2001]Mars Maps
    Lost Cow
    李超线段树
    多种方法求解Pku3468 A Simple Problem with Integers
    陈老师的福利
    leetcode 673. 最长递增子序列的个数
    #10043.「一本通 2.2 例 1」剪花布条
    PTA7-1
    6-1 实验三哈夫曼树 (15分)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3339671.html
Copyright © 2011-2022 走看看