I/O编程基础知识

编程语言的I/O类库中常常使用流这个抽象的概念,它代表任何有能力产生数据的数据源对象或时有能力接收数据的接收端对象。“流”概念源于UNIX中的管道(pipe)的概念。在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等,它屏蔽了实际的I/O设备中处理数据的细节。 一个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是Internet上的某个URL。

1 :流:一组有序的数据序列。

2:字节流:数据流中最小的数据单元是字节。
3:字符流:数据流中最小的数据单元是字符。
 
C++的输入输出流库
    流类形成的层次结构就构成流类库,即流库。与C 语言中的输入/输出流库一样,C++的输入输出流库不是语言的一部分,而是作为一个独立的函数库提供的。因此,在使用时需要包含相应的头文件。
     流在使用前要被建立,使用后要被删除。
     C++实现了三种输入输出方法:
  1. 标准I/O---键盘,显示器
  2. 文件I/O---磁盘文件
  3. 串I/O ---内存
输入输出派生类体系
 
                                       图1 流类库体系结构
 
 
       由图1 中可以看出,类ios 是所有基本流类的基类,提供了进行I/O 处理的基本操作,其他基本流类都派生自它,输入类istream 与输出类ostream 继承了ios 类,各专门负责提供输入/输出操作的成员函数,使流对象能通过其成员函数完成数据传输的任务;输入/输出类iostream 同时继承了输入类istream 和输出类ostream,该类没有提供新的成员函数,只单纯地将输入类istream 和输出类ostream 结合起来;I/O 文件流类fstream 和I/O 字符串流类strstream 继承了输入/输出类iostream。
       streambuf主要作为其他类的支持,定义了对缓冲区的通用操作,如设置缓冲区,从缓冲区中读取数据,或向缓冲区写入数据等操作;filebuf类使用文件来保存缓冲区中的字符序列。它定义了文件读、写、打开、关闭等常用操作。  
       为了便于程序数据的输入/输出,C++预定义了几个标准输入/输出流对象。在程序中可以直接引用它们来输入/输出数据。
对 象 定 义         说    明
ostream cout;  cout与标准输出设备相关联
ostream cerr;  cerr与标准错误输出设备相关联(非缓冲方式)
ostream clog;  clog与标准错误输出设备相关联(缓冲方式)
istream cin;   与标准输入设备相关联
分类说明:
      C++将文件看成是一个个字符在磁盘上的有序集合,用流来实现文件的读写操作 。
与文件相关的流
ifstream
ofstream
fstream 
用流操作文件的过程,须经过以下4个步骤
(1)建立文件流
ifstream iFile;               
ofstream oFile;               
fstream ioFile; 
(2)打开文件 
void open(const char *filename,int mode,int access);
(3)访问文件
(4)关闭文件
iFile.close();
oFile.close();
     

java.io包中的类     

 

stream(包括Inputstream和Out stream)都包括两种类型:
(1)字节流
表示以字节为单位从stream中读取或往stream中写入信息,即io包中的inputstream类和outputstream类的派生类。通常用来读取二进制数据,如图象和声音。

(2)字符流
以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream中写入信息。

原先的I/O类库只支持8位的字节流,因此不可能很好地处理16位的Unicode字符流。Unicode是国际化的字符集(更何况Java内置的char就是16位的Unicode字符),这样加了Reader和Writer之后,所有的I/O就都支持Unicode了。此外新类库的性能也比旧的好。

但是,Read和Write并不是取代InputStream和OutputStream,有时,你还必须同时使用"基于byte的类"和"基于字符的类"。为此,它还提供了两个"适配器(adapter)"类。InputStreamReader负责将InputStream转化成Reader,而OutputStreamWriter则将OutputStream转化成Writer。

java的常用输入、输出流其实都是继承自4个抽象类,分别是
基于单字节的InputStream,OutputStream类(面向字节形式的I/O)
基于双字节的Unicode代码单元的 Reader, Writer类(面向字符形式的I/O)


 

一.流的层次结构

结构图如下:输入流:

输出流

 

inputstream类和outputstream类都为抽象类,不能创建对象,可以通过子类来实例化。

 

1、以字节(Byte)为导向的输入流(InputStream系列),这几个类都可以与FileInputStream对象相连以提供有用接口:

1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
2) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作(文件名、文件、FileDescriptor对象)
3) PipedInputStream:实现了pipe的概念,主要在线程中使用(作为多进程中的数据源)
4) SequenceInputStream:把多个InputStream合并为一个InputStream
 StringBufferInputStream 已弃用。
 
以字节(Byte)为导向的输出流(OutputStream系列),可以与FilterOutputStream对象相连以提供有用接口:
1) ByteArrayOutputStream:在内存中创建缓冲区,把信息存入内存中的一个缓冲区中,缓冲区初始化尺寸(可选)
2) FileOutputStream:把信息存入文件中(文件名、文件、FileDescriptor)
3) PipedOutputStream:实现了pipe的概念,主要在线程中使用(指定用于多线程的数据的目的地)

 

2、两种不同导向的stream之间的转换(使用适配器类)

InputStreamReader和OutputStreamReader:把一个以字节为导向的stream转换成一个以字符为导向的stream。 
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集 

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集

 

使用"分层对象(layered objects)",为单个对象动态地,透明地添加功能的做法,被称为Decorator Pattern。Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。这使得decorator的用法变得非常的透明--无论对象是否被decorate过,传给它的消息总是相同的。这也是Java I/O类库要有"filter(过滤器)"类的原因:抽象的"filter"类是所有decorator的基类。Decorator模式常用于如下的情形:如果用继承来解决各种需求的话,类的数量会多到不切实际的地步。Java的I/O类库需要提供很多功能的组合,于是decorator模式就有了用武之地。

 

3、通过FilterInputStream从InputStream读取数据:

1) DataInputStream:从stream中读取基本类型(intchar,long等)数据。 
2) BufferedInputStream:使用缓冲区 ,使用它可以防止每次读取都得进行实际的读操作
3) LineNumberInputStream:会记录input stream内的行数,然后可调用getLineNumber()和setLineNumber(int) 
4) PushbackInputStream:很少用到,一般用于编译器开发
 
通过FilterOutputStream向OutputStream写入:
1) DataIOutputStream:可以按照移植方式往stream中输出基本类型(intchar,long等)数据。 
2) BufferedOutputStream:使用缓冲区 ,使用它可避免每次发送数据都进行实际的写操作
3) PrintStream:产生格式化输出 ,其中DataOutputStream处理数据的存储,PrintStream处理显示

 

4、更改流的行为:

尽管BufferedOutputStream是FilterOutputStream的子类,但是BufferedWriter并不是FilterWriter的子类,(FilterWriter是抽象类,没有任何子类)

1) 没有与DataInputStream对应的类。除非在要使用readLine()时改用BufferedReader,否则使用DataInputStream 
2) BufferedReader:与BufferedInputStream对应 
3) LineNumberReader:与LineNumberInputStream对应 
4) PushBackReader:与PushbackInputStream对应 
5) BufferedWrite:与BufferedOutStream对应 
6) PrintWrite:与 PrintStream对应 

 

5、自我独立的类:RandomAccessFile:

这个类适用于有大小已知的记录组成的文件,RandomAccessFile除了实现了DataInput和DataOutput接口(DataInputStream和DataOutputStream也实现了这两个接口)之外,这个类是个完全独立的类,它拥有和别的I/O类型本质不同的行为,可以在一个文件内向前和向后移动,直接从Object派生而来。

1) 可通过RandomAccessFile对象完成对文件的读写操作 
2) 在产生一个对象时,可指明要打开的文件的性质:r,只读;w,只写;rw可读写 
3) 可以直接跳到文件中指定的位置 
RandomAccessFile的大部分功能(不是全部)有nio存储映射文件所取代

6、字符流的读取和写入

java.io.Reader 和 java.io.InputStream 组成了 Java 输入类。Reader 用于读入16位字符,也就是 Unicode 编码的字符;而 InputStream 用于读入 ASCII 字符和二进制数据。

八.字符流的读取和写入

java.io.Reader 和 java.io.InputStream 组成了 Java 输入类。Reader 用于读入16位字符,也就是 Unicode 编码的字符;而 InputStream 用于读入 ASCII 字符和二进制数据。
Reader的体系结构

 

 

 

Writer类体系结构

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值