• linux 标准I/O (二)


    <Uinx 环境高级编程笔记>
     
    以前经常遇到两种I/O操作
    一类是f打头的fopen, fread, fwrite
    一类是没有f打头的open, read, fwrite
    原来一个是UNIX I/O(在类Unix系统上实现),另一类是标准I/O(在很多系统上都有实现,包括windows)
     

    使用标准I/O的好处

    因为在出UNIX的很多操作系统(包括Windows, linux)上都实现了此库,所有有利于软件的移植。
     
    与UnixI/O的主要区别
    UNIX I/O的函数都是针对文件描述符的,而标准I/O的操作都是围绕流进行的。所为的流就是一个FILE *
    标准I/O提供了缓存--为了尽量减少write, read的调用。
    标准I/O的效率会低一些,因为它是多了一层封装。即,fread通过调用read来实现。
     
    标准I/O的头文件
    stdio.h
    三个标准I/O流预定义指针:stdin, stdout, stderr
    (Unix I/O: STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO)
     
    缓存
    有缓存就会有延迟,即输出设备上的内容和缓存中的内容很可能不一样。可以调用fflush刷新缓存。
    有多种缓存类型,可以调用下面的API来更改默认缓存类型。
    setbuf,  setvbuf
    setvbuf可以精确的说明缓存的类型。
    fclose关闭流时也会刷新流。
    当一个进程正常终止时(直接调用exit,或从main函数返回),则所有带未写缓存数据的标准I/O流都会被刷新,所有打开的标准I/O流都会被关闭。
     
    标准I/O API
    打开流
    FILE * fopen(const char * path,const char * mode);
    mode参数很简单:
    r    文件只读
    r+  文件可读写,文件必须存在
    w   文件只写。相当于删除原文件,创建一个新文件。即若文件存在,长度变为0。若文件不存在,则创建。
    w+ 文件可读写。其它和w相同。
    a    以附加方式打开只写文件。文件不存在,会自动创建。
    a+ 以附加方式打开读写文件。文件不存在,会自动创建。
    b    以二进制方式操作文件。可以和上面的任意一个组合。
    自动创建的文件访问权限位:644
    读写流
    每次一个字符的I/O
    getc, fgetc, getchar
    getc一般是宏调用,效率高于fgetc。fgetc可以作为一个地址传递给其它函数。
    int getc(FILE * stream);
    int fgetc(FILE *stream);
    int getchar(void) 相当于 getc(stdin);
    从一个流读取一个字符后,可以调用ungetc将字符再送回流中。
    上面三个API出错或到达文件尾都返回-1。具体是什么情况,需要调用下面的两个API来判断:
    int ferror(FILE *stream);
    int feof(FILE *stream);
    什么情况下会用到回送字符呢?
    当正在读一个输入流,并进行某种形式的分字或分记号操作时,会经常用到回送字符操作。
    有时需要先看一看下一个字符,以决定如何处理当前字符。然后就需要方便地将刚查看的字符
    送回,以便下一次调用g e t c时返回该字符。
    对应的输出:
    putc, fputc, putchar
     
    每次一行的I/O
    gets, fgets
    char * fgets(char * s,int size,FILE * stream);
    char *gets(char *s);
    fgets从文件读入, gets从表中输入读入。
    fgets()用来从参数 stream所指的文件内读入字符并存到参s所指的内存空间,直到出现换行字符、读到文件尾或是已读了 size-1个字符为止,最后会加上 NULL作为字符串结束。换行符也包含在字符串中。去除换行符:s[strlen(s)-1]=0;
    gets会自动删除新行符。建议不要使用gets,因为容易造成缓冲区溢出。
    对应的输出:
    fputs 之后不会输出一个新行符
    puts 之后会输出一个新行符
     
    指定长度的I/O
    上面的API主要用来处理文本文件,对于结构类型的内容或结构中含有null字符或换行符的情况,不好处理。这就用到下面两个API。
    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);
    两个函数都返回实际读写的对象数。
     
    定位流
    long ftell(FILE * stream);
    int fseek(FILE * stream,long offset,int whence);
    void rewind(FILE * stream);  相当于fseek(stream, 0, SEEK_SET);
    下面两个的可移植性会好些
    int  fgetpos(FILE *, fpos_t *);
    int fsetpos(FILE *, const fpos_t *);
     
    格式化I/O
    printf将格式化数据写到标准输出,fprintf写至指定的流,sprintf将格式化的字符送入数组buf中。
    sprintf在该数组的尾端自动加一个null字节,但该字节不包括在返回值中。
    int fprintf(FILE * stream, const char * format,.......);
    int sprintf( char *str,const char * format,.........);
    int printf(const char * format,.......);
     
    对应的三个格式化输入
    int fscanf(FILE * stream, const char * format,.......);
    int sscanf( char *str,const char * format,.........);
    int scanf(const char * format,.......);
    标准I/O的实现细节
    在UNIX上,标准I/O是调用UNIX的I/O来实现的,类似
    fread()
    {
      ……
      read()
      ……
    }
    每个流都有对应的文件描述符
    可以调用int fileno(FILE *fp)来获得,如果要调用dup或fcntl等函数,需要用到这个转换。
     
    创建临时文件
    FILE *tmpfile(void) -- linux下可用
    char *tmpnam(const char *)  -- linux下不可用
    char *tempnam(const char *dir, const char *prefix); -- linux下不可用
     
    char * mktemp(char * template); -- linux下可用
    参数 template所指的文件名称字符串中最后六个字符必须是 XXXXXX。
    linux下的一个例子:
    char template[ ]="aaaaa-XXXXXX"; 
    mktemp(template);
    或 mkdtemp(template);
  • 相关阅读:
    Struts2 (二)入门
    Struts2 (一)入门
    Hibernate 配置和注解式 ,关联关系
    Hibernate入门,HQL,双向表关联关系
    web自定义标签
    Spring整合MyBatis 基础
    PHP字符串——字符串函数
    php功能模块学习笔记
    PHP常用符号和函数
    asp xmlhttp 读取文件
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/4160165.html
Copyright © 2020-2023  润新知