Linux操作系统—标准IO库(3)(2015-8-5)

分类:Linux操作系统

二进制IO和定位流

  二进制I/O也称直接I/O,一个一个对象的I/O,面向记录的I/O或面向结构的I/O。每次I/O操作读取或写一定数量的对象,而每个对象具有指定的长度。常用于二进制文件中读或向二进制文件中写一个结构。

读取二进制流

  使用fread函数可以进行二进制数据的读取。

#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);

  函数fread的各参数和返回值的含义如下:
1. ptr:输入缓存
2. size:数据块的大小
3. nitems:数据块的个数
4. stream:流文件指针
5. 返回值:返回实际读取到的数据块的个数。如果次数字小于nitems,则表示出错或到达文件尾端,应调用ferror或feof以判断究竟是哪一种情况

  这个函数参数有点多,还是找一个使用的例子来看看

nRead = fread(buf, sizeof(unsigned char), BUFFSIZE, fpIn);

  这一小段代码的作用是:调用fread函数从源文件中读取BUFFSIZE各字节。fpIn是源文件的流指针,BUFFSIZE是数据块的个数,sizeof(unsigned char)是数据块的大小,也即是一个字符的大小,buf是输入的缓存,也即是fread读取的数据存放的地方。fread返回的是实际读取的字符数,该数值被记录在了变量nRead中。
  实际读取的数据块的个数nRead如果小于预定的BUFFSIZE,则表示出错或者到达文件尾端,应调用ferror或feof以判断究竟是哪中情况。

写二进制流

  使用fwrite函数可以进行二进制数据块的输出。

#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);

  函数fwrite的各参数和返回值的含义如下:
1. ptr:待输出的数据的
2. size:数据块的大小
3. nitems:数据块的个数
4. stream:流文件的指针
5. 返回值:返回实际输出的数据块的个数,如果小于nitems,则表示出错。

  总结这两个函数(不严谨,但可以这样区分两者):
- fread:从stream流中读取数据存入ptr中
- fwrite:从ptr总读取数据存入stream中

二进制I/O的常见用法

  • 读或写一个二进制数组。例如:
float data[10]
...
if (fwrite(&data[2], sizeof(float), 4, fp) !=  4)printf("fwrite error.\n");

  这段代码调用fwrite向文件流写入data数组从第3个元素起的连续4个元素,每个数据块的大小为一个元素(一个浮点数)的大小,如果写入的元素个数不为4,则说明发生了错误。

  • 读或写一个结构。此时,指定size为结构体的大小,nitems指定为1。例如:
struct {short count;long total;char name[NAMESIZE];
}item;
...
if (fwrite(&item, sizeof(item), 1, fp) != 1)printf("fwrite error");

  这段代码盗用fwrite向文件流写入结构体变量item,数据块为1,返回值如果不为1,则说明发生了错误。

  • 以上二者的结合。如:向一个结构体数组内写数据。

二进制I/O实践篇

目标:实现简单的问价复制功能

#include <stdio.h>
#include <stdlib.h>
#define     BUFFSIZE    80  int main(int argc, char *argv[])
{FILE *fpIn, *fpOut;int nRead, nWrite;unsigned char buf[BUFFSIZE];if (argc != 3){         /* 如果从命令行传递过来的参数的个数不是3个 */                                          printf("Usage : %s <source_file> <destination_file>\n", argv[0]);return -1;}/* 如果要被复制的文件无法打开被读取 */if ((fpIn = fopen(argv[1], "r")) == NULL){printf("Cannot open file [%s] for reading.\n", argv[1]);return -1;}/* 如果复制过来的新文件无法打开被写入 */if ((fpOut = fopen(argv[2], "w")) == NULL){printf("Cannot open file [%s] for writing.\n", argv[2]);return -1;}/* 当要被复制的文件没有到达文件尾时 */while (!feof(fpIn)){nRead = fread(buf, sizeof(unsigned char), BUFFSIZE, fpIn);if (nRead < BUFFSIZE){if (ferror(fpIn)){              /* 如果读取出错了 */printf("Copy failed.\n");break;}}if (nRead > 0){                     /* 进行复制操作 */nWrite = fwrite(buf, sizeof(unsigned char), nRead, fpOut);if (nWrite != nRead){           /* 如果复制出错了 */printf("Copy failed.\n");break;}}}fclose(fpOut);                          /* 将文件关闭 */fclose(fpIn);return 0;
}

  编译并运行

biantiao@lazybone1994-ThinkPad-E430:~/桌面$ gcc -o ioCopy ioCopy.c
biantiao@lazybone1994-ThinkPad-E430:~/桌面$ ./ioCopy
Usage : ./ioCopy <source_file> <destination_file>
biantiao@lazybone1994-ThinkPad-E430:~/桌面$ ./ioCopy a.txt b.txt
Cannot open file [a.txt] for reading.
biantiao@lazybone1994-ThinkPad-E430:~/桌面$ touch a.txt
biantiao@lazybone1994-ThinkPad-E430:~/桌面$ ./ioCopy a.txt b.txt
biantiao@lazybone1994-ThinkPad-E430:~/桌面$ ls
a.txt  b.txt  ioCopy  ioCopy.c
biantiao@lazybone1994-ThinkPad-E430:~/桌面$

  你可以发现参数argv[0]不是ioCopy而是./ioCopy,如果你不想在运行时加入./,就把ioCopy程序文件放入bin目录下好了。

定位流

  可以调用fseek来定位流文件的读写指针。

#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);

  函数fseek的各参数和返回值的含义如下:
1. stream:流文件的指针
2. offset:位移量
3. whence:指定位移量相对于何处开始。whence可以取如下三个常量

  • SEEK_SET:文件开始位置
  • SEEK_CUR:文件指针当前位置
  • SEEK_END:未见结束位置

4 返回值:成功返回0,失败返回-1,错误记录在errno

  一次成功的调用ftell()会清除流结束标志,并会撤销已调用的ungetc()对流的影响。调用rewind()函数可以将一个流的读写指针设置到文件的起始位置。其原型如下:

#include <stdio.h>
void rewind(FILE *stream);

  该函数的唯一参数是已打开流的流文件指针。调用rewind(fp)基本等同于调用fseek(stream, 0L, SEEK_SET)。稍微不同的是,rewind函数将在读写指针设置到文件的起始位置时同时会将出错指示errno清0
  调用ftell()函数可以获得一个流的读写指针的当前位置。该函数的原型如下:

#include <stdio.h>
long ftell(FILE *stream);

  该函数返回读写指针当前相对于文件起始位置的位移量;若出错,则返回-1,错误记录在errno中。

Linux操作系统-标准IO库(3)相关推荐

  1. Linux操作系统-标准IO库(2)

    Linux操作系统-标准IO库(2)(2015-8-4) 分类:Linux操作系统   打开一个流后,可采用三种不同类型的非格式化I/O对其进行读,写操作. 1. 每次读取一个字符的I/O 2. 每次 ...

  2. Linux操作系统-标准IO库(1)

    Linux操作系统-标准I/O库(1)(2015-8-3) 分类:Linux操作系统   不仅在linux,在很多操作系统上都实现了标准I/O库,该库由ANSI C标准说明.标准I/O库是在系统调用函 ...

  3. 【Linux】标准IO库

    Linux系统的文件IO都是针对文件描述符的,而标准IO(ISO C)的操作则是围绕流进行的,一个最明显的区别是标准IO比Linux文件IO多了缓冲机制.为了使用流,需要用到文件指针即指向FILE结构 ...

  4. linux 流函数,标准IO函数库 - 二进制文件IO,流定位,创建临时文件和内存流

    1 二进制IO(Binary IO) 在前一篇我们了解了逐字符读写和逐行读写函数. 如果我们在读写二进制文件,希望以此读写整个文件内容,这两个函数虽然可以实现,但是明显会很麻烦且多次循环明显效率很低. ...

  5. Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)

    1.linux系统如何管理文件 硬盘中的静态文件和inode: (1)硬盘分为两大区域:一个是硬盘内容管理表项,另一个是真正存储内容的区域.先去读取硬盘内容管理表,找到要访问的存储内容的区域,再用得到 ...

  6. Linux后台开发系列之「13.标准 IO 库」

    StdIO.png 版权声明:本文为 cdeveloper 原创文章,可以随意转载,但必须在明确位置注明出处! 标准 IO 库 上一篇文章我们学习了 5 个底层的 IO 函数,这次我们来学习标准的 I ...

  7. 标准IO库--unix环境高级编程读书笔记

    标准IO库是C语言提供的一个库,不光存在于linux中,在windows中也是有的.标准IO库和文件IO的不同是,标准IO库是对文件IO(即系统调用)的封装,并且在用户层添加了一些缓冲区. 文件IO的 ...

  8. 在标准IO库中,rewind函数作用?

    在标准IO库中,rewind函数作用? 将文件内部的位置指针重新指向一个流(数据流/文件)的开头 一个完整的信号生命周期包含4个重要的事件,这4个重要事件分别是? 信号诞生:信号在进程中注册完毕:信号 ...

  9. C++ Primer 第八章 标准IO库

    学习本章内容之前有必要对缓冲区的概念做一个基本了解,我引用了网上一片文章<C++编程对缓冲区的理解>,内容如下: 什么是缓冲区    缓冲区又称为缓存,它是内存空间的一部分.也就是说,在内 ...

最新文章

  1. UI培训教程分享:常用的商业插画风格有哪些?
  2. oracletns中不存在名称为_oracle tnsname.ora中的SERVICE_NAME 代表实例的名称还是代表全局数据库的名称?...
  3. 编译Mysql 5.5时报do_abi_check错误
  4. 我的swagger上面怎么没有models_浅析特斯拉Model S的采样板
  5. 【学习笔记】APP测试基本流程及测试要点
  6. java 全局代码区_MyEclipse设置全局编码
  7. 小微型计算机2018北大核心,2018年全国北大中文核心期刊目录
  8. 震惊!Spring Boot 内存又泄露,排查太难了!
  9. 试分析家用变频空调的计算机控制原理,习 题 五
  10. 全网首发:No package ‘usbutils‘ found
  11. 存储器容量相关概念及计算
  12. Linux学习日记之初始用户管理
  13. oracle银行借贷系统,Oracle ERP系統借贷关系表
  14. 如何学计算机打字,电脑怎么学打字
  15. Win10样式管理与夜间模式
  16. 厦门大学计算机科学专业,2018厦门大学计算机科学系考研招生信息汇总
  17. 2023年百度SEO优化要怎么做
  18. 网站文章采集、撰写、推广注意要点
  19. debian下cron的使用方法和常见问题
  20. 当 AI 掌握「读心术」:DeepMind AI 已经学会相互理解

热门文章

  1. 神经网络过拟合什么意思,神经网络过拟合现象
  2. GPU通信技术-GPUDirect P2P
  3. Snort入门(一)
  4. DeepLab v3最先进的图形分割网络学习
  5. 【学习笔记】设计模式-原型模式/克隆模式(Prototype)
  6. STM8L051F3_0b_开发环境搭建
  7. Getting things done(搞定)思维导图
  8. 郑州计算机中专学校排名,郑州市中专十大学校排名
  9. Python游戏开发,pygame模块,Python实现接水果和金币小游戏
  10. 企微消息分享小程序 出现第一次能打开,第二次打开卡在白屏的情况