<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);

linux 标准I/O (二)的更多相关文章

  1. linux磁盘管理系列二:软RAID的实现

    磁盘管理系列 linux磁盘管理系列一:磁盘配额管理   http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_linux_040_quota.html l ...

  2. Linux内存管理(二)

    Linux内存管理之二:Linux在X86上的虚拟内存管理 本文档来自网络,并稍有改动. 前言 Linux支持很多硬件运行平台,常用的有:Intel X86,Alpha,Sparc等.对于不能够通用的 ...

  3. Linux标准IO和管道

    Linux标准IO和管道 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.标准输入和输出 程序:指令+数据 读入数据:Input 输出数据:Output 打开的文件都有一个fd: ...

  4. Linux 反弹shell(二)反弹shell的本质

    Linux 反弹shell(二)反弹shell的本质 from:https://xz.aliyun.com/t/2549 0X00 前言 在上一篇文章 Linux反弹shell(一)文件描述符与重定向 ...

  5. Linux shell脚本编程(二)

    Linux shell脚本编程(二) 练习:求100以内所有偶数之和; 使用至少三种方法实现; 示例1: #!/bin/bash # declare -i sum=0 #声明一个变量求和,初始值为0 ...

  6. Linux学习之CentOS(二十二)--单用户模式下修改Root用户的密码

    在上一篇随笔里面详细讲解了Linux系统的启动过程 (Linux学习之CentOS(二十一)--Linux系统启动详解),我们知道Linux系统的启动级别一共有6种级别,通过 /etc/inittab ...

  7. linux标准io的copy

    ---恢复内容开始--- 1.linux标准io的copy #include<stdio.h> int main(int argc,char **argv) { if(argc<3) ...

  8. Linux 标准目录结构

    初学Linux,首先需要弄清Linux 标准目录结构 / root --- 启动Linux时使用的一些核心文件.如操作系统内核.引导程序Grub等. home --- 存储普通用户的个人文件 ftp ...

  9. Android RecyclerView单击、长按事件:基于OnItemTouchListener +GestureDetector标准实现(二),封装抽取成通用工具类

     Android RecyclerView单击.长按事件:基于OnItemTouchListener +GestureDetector标准实现(二),封装抽取成通用工具类 我写的附录文章2,介绍了 ...

随机推荐

  1. SPOJ AMR10I 递归

    DES :给你n 块石头.不会超过70.把它们分成n堆.每堆里的石头数做积.问共有多少个数.最终的结果除了1之外都能分解成素数相乘或者素数相乘再乘1.所以可以找到所有不超过70的素数然后进行深搜. 感 ...

  2. Oracle 数据库分析

    一.数据库分析 二.表的分析 1.分析表exec dbms_stats.gather_table_stats('SFISM4','R_SN_DETAIL_T',CASCADE=>TRUE);ex ...

  3. pymysql 返回数据为字典形式(key:value--列:值)

    一.需求 在数据库的操作中,有时需要直接返回数据库表中的栏位名称+栏位值的key:value这种字典格式的方法. Python DB-API使用流程: 引入API模块. 获取与数据库的连接. 执行SQ ...

  4. float、clear、overflow

    浮动: float:  none|left|right 作用使得标签失去块级标签的独占一行效果,向某个方向靠拢 标签浮动了,也需要占地方,有时候出现未浮动的div覆盖部分浮动div是浏览器的bug情况 ...

  5. 关于junk jack

    旨在利用一切物品打造你自己的世界.你需要砍树获得木头,挖各种矿石用火炉炼成不同东西,顺便得到不同颜色材质的石头建房子,打各种家禽获得吃的甚至烘焙.养起来繁殖,天上掉下的星星.捡到圣诞礼包中的袜子都可以 ...

  6. 详细介绍C++STL:unordered_map

    不得不提一下,hash_map未加入在C++11标准中. 在VC中编译: #include <hash_map> using namespace stdext; hash_map<i ...

  7. 解决:编辑一条彩信,附件选择添加音频,返回到编辑界面选择play,不能播放,没有声音

    [操作步骤]:编辑一条彩信,附件选择添加音频(外部音频),返回到编辑界面选择play,菜单键选择view slideshow [测试结果]:不能播放,没有声音 [预期结果]:可以播放 根据以往的经验( ...

  8. C++/C 宏定义(define)中# ## 的含义 宏拼接

    C++/C 宏定义(define)中# ## 的含义 define 中的# ## 一般是用来拼接字符串的,但是实际使用过程中,有哪些细微的差别呢,我们通过几个例子来看看. #是字符串化的意思,出现在宏 ...

  9. node+mongoose使用例子

    https://github.com/Aquarius1993/nodeNotes 功能 1. 注册 2. 登录 3. 修改密码 4. 修改头像 5. 获取用户笔记 6. 添加,删除,更新笔记 安装部 ...

  10. CodeForces - 285E: Positions in Permutations(DP+组合数+容斥)

    Permutation p is an ordered set of integers p1,  p2,  ...,  pn, consisting of n distinct positive in ...