I/O小总结1

对于一块芯片,I/O和中断时必不可少的。
在OS中,I/O的概念很多,很杂;很难全部记清楚。
I/O是CPU与外设(包括内存、硬盘、键盘、鼠标、打印机等)之间通信的桥梁。
在linux中,一切都是文件,所以linux下I/O编程一般都是针对文件编程。

I/O大致可分为三类:
1.对系统指定的标准设备的输入和输出;即从键盘输入数据,输出到显示器屏幕;称为为标准I/O.
2.以外存磁盘文件为对象进行输入输出,称为文件I/O.文件IO是不带缓存的IO.
3.对内存中指定的空间进行输入输出;通常指定一个字符数组作为存储空间,称为字符串I/O.

I/O具体操作方式有:
1.底层I/O操作(open, read, lseek, write, close),底层I/O是不带缓存的I/O.
 
2.C流I/O
  字符读写函数  :fgetc和fputc
  字符串读写函数:fgets和fputs
  格式化读写函数:fscanf和fprinf
  二进制、数据块读写函数:freed和fwrite
 
3.面向对象C++流I/O 
  iostream:定义读写控制窗口的类型
  fstream:定义读写已命名文件的类型。
  sstream:读写内存中string对象
 
  文本文件读写:<<,>>  (>>会跳过空白,不能读入带空格的字符串)
  字符逐行读写: getline
  单个字符数据的输入读写:put, get 
  二进制、读写数据块:read, write
 
 
下面这段测试代码用于测试3种IO操作读写二进制文件效率。
结论是:文件I/O最慢,C流I/O和面向对象C++流I/O 差不多(C++流稍快)。

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int test_io_efficiency()
{
  char buffer[1024];
  timeval tv;
  timeval tv2, tv3, tv4, tv5, tv6;
  long long L1, L2, L3, L4, L5, L6;
  int i;
  
  /*****************文件I/O测试********************/
  int fileA, fileB;
  if(( fileA= open("source.rar", O_RDONLY))<0)  //open() 是系统调用 返回的是文件句柄,文件的句柄是文件在文件描述副表里的索引,fopen()是C的库函数,返回的是一个指向文件结构的指针。
    return 0;
  if((fileB= open("destinationA.rar", O_RDWR|O_CREAT|O_TRUNC))<0)  //如果文件存在,会直接退出
    return 0;  
  
  int fileA2 = dup(fileA); //test, 复制一个文件描述符2
  if(fileA2 == -1)
  {
    printf("dup failed \n");
	return 0;
  }  

  int fileA3;
  if((fileA3 =fcntl(fileA2, F_DUPFD, 0))<0)//test, 复制一个文件描述符3
  {
    printf("fcntl dup failed \n");
	return 0;
  }
  
  int len= lseek(fileA3,0,SEEK_END);    //文件的长度,从0开始
  printf("lseek end len  %d\n",len);   	
  len =lseek(fileA3,0,SEEK_SET); // 从826132252开始读起
  printf("lseek set len  %d\n",len);   	
	
  gettimeofday(&tv, NULL);
  L1 = tv.tv_sec*1000*1000+tv.tv_usec;  	
	
  //while((i= read(fileA,buffer, 1024))>0)	 
  while((i= read(fileA3,buffer, 512))>0) //为了效果明显,3种IO操作buffer大小都为512
  {
    write(fileB, buffer, i);
  }
   
  close(fileA);
  close(fileB);  
  
  gettimeofday(&tv2, NULL);
  L2 = tv2.tv_sec*1000*1000+tv2.tv_usec;
  printf("%lld\n",L2-L1);  //打印出I/O读写总时间
  
  
  
  /*****************C 标准I/O测试********************/
  gettimeofday(&tv3, NULL);
  L3 = tv3.tv_sec*1000*1000+tv3.tv_usec;
  
  FILE *fileC, *fileD;
  if((fileC = fopen("source.rar","rb")) == NULL) 
	return 0;
  if((fileD = fopen("destinationB.rar","wb+")) == NULL) 
	return 0;	
  //fread(读入数据的存放地址, size要读写的字节数, 要进行读写多少个size字节的数据项, 文件指针)
  while((i= fread(buffer,1,512,fileC))>0) 
  {
    fwrite(buffer,1,i,fileD);
  }
  fclose(fileC);
  fclose(fileD);
  
  gettimeofday(&tv4, NULL);
  L4 = tv4.tv_sec*1000*1000+tv4.tv_usec;
  printf("%lld\n",L4-L3);
  
    
  /*****************C++ 面向对象I/O测试********************/
  gettimeofday(&tv5, NULL);
  L5 = tv5.tv_sec*1000*1000+tv5.tv_usec;
  ifstream inPut;
  inPut.open("./source.rar", ios::binary);
  if (!inPut.good())
  {
    inPut.close();
    return 0;
  }		
  
  ofstream outPut;
  outPut.open("./destinationC.rar", ios::binary);
  if(!outPut)
  {
	outPut.close();
	return 0;
  }
   
  while(!(inPut.eof()))
  {
	//inPut.getline(buffer, 1024);
	inPut.read(buffer, 512);
	//if (strlen(buffer) == 0)
	//    continue;
	outPut.write(buffer, 512);
	//outPut.flush(); //如果每次都flush,效率会很低
  }
	
  inPut.close(); 
  outPut.close();
  gettimeofday(&tv6, NULL);
  L6 = tv6.tv_sec*1000*1000+tv6.tv_usec;
  printf("%lld\n",L6-L5);
  
  return 1;
}

int main()
{
  test_io_efficiency();
  return 1;
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值