`
xiaoheliushuiya
  • 浏览: 401732 次
文章分类
社区版块
存档分类
最新评论

Java 7源码分析第12篇 - 输入输出流

 
阅读更多
stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。Java的I/O操作类在java.io包下,这些类可以大概分为两类,操作字节流的和操作字符流的类:
(1)字节流
表示以字节为单位从stream中读取或往stream中写入信息,即io包中的inputstream类和outputstream类的派生类。通常用来读取二进制数据,如图象和声音。
(2)字符流

以Unicode字符为单位从stream中读取或往stream中写入信息。


1、字节输入流


下面来看一下操作字节输入流的类的框架结构:


可以看到:

1.InputStream是所有的输入字节流的父类,它是一个抽象类。

2. ByteArrayInputStreamStringBufferInputStreamFileInputStream是三种基本的介质流,它们分别将Byte数组、StringBuffer、和本地文件中读取数据。PipedInputStream是从与其它线程共用的管道中读取数据。
3. ObjectInputStream和所有FilterInputStream的子类都是装饰流。

详细的介绍如下:


功能

如何构造

怎样使用

ByteArrayInputStream

将内存中的Byte数组适配为

一个InputStream

从内存中的Byte数组创建该对象(2种方法)

一般作为数据源,会使用其它装饰流提供额外的功能,一般都建议加个缓冲功能。

StringBufferInputStream

将内存中的字符串适配为一

InputStream

从一个String对象创建该对象。底层的实现使用StringBuffer。该类被Deprecated

主要原因是StringBuffer不应该属于字节流,所以推荐使用StringReader

一般作为数据源,同样会使用其它装饰器提供额外的功能。

FileInputStream

最基本的文件输入流。主要

用于从文件中读取信息。

通过一个代表文件路径的StringFile对象或者FileDescriptor对象创建。

一般作为数据源,同样会使用其它装饰器提供额外的功能。

PipedInputStream

读取从对应PipedOutputStream

写入的数据。在流中实现了管道的概念。

利用对应的PipedOutputStream创建。

在多线程程序中作为数据源,同样会使用其它装饰器提供额外的功能。

SequenceInputStream

2个或者多个InputStream对象转

变为一个InputStream.

使用两个InputStream或者内部对象为InputStreamEnumeration对象创建该对象。

一般作为数据源,同样会使用其它装饰器提供额外的功能。

FilterInputStream

给其它被装饰对象提供额外功能的抽

象类

主要子类见下表

在FilterInputStream类下还有一些具体的子类,如下图:



功能

如何构造

怎样使用

DataInputStream

一般和DataOutputStream配对使用,完成基本数据类型的读写。

利用一个InputStream构造。

提供了大量的读取基本数据类新的读取方法。

BufferedInputStream

使用该对象阻止每次读取一个字节都会频繁操作IO

将字节读取一个缓存区,从缓存区读取。

利用一个InputStream、或者带上一个自定义的缓存区的大小构造。

使用InputStream的方法读取,只是背后多一个缓存的功能。

LineNumberInputStream

跟踪输入流中的行号。可以调用getLineNumber()

setLineNumber(int)方法得到和设置行号。

利用一个InputStream构造。

紧紧增加一个行号。可以象使用其它InputStream一样使用。

PushbackInputStream

可以在读取最后一个byte后将其放回到缓存中。

利用一个InputStream构造。

一般仅仅会在设计compilerscanner时会用到这个类。一般很少用到。


2、字节输出流


看一下操作字节输出流的类的框架结构:


可以看到:

1.OutputStream是所有的输出字节流的父类,它是一个抽象类。

2. ByteArrayOutputStreamFileOutputStream是两种基本的介质流,它们分别向Byte数组、和本地文件中写入数据。PipedOutputStream是向与其它线程共用的管道中写入数据,

3. ObjectOutputStream和所有FilterOutputStream的子类都是装饰流。下表列出了输出字节流的功能及如何使用它们。

来看一下各个类的具体介绍:


功能

如何构造

怎样使用

ByteArrayOutputStream

在内存中创建一个buffer。所有写

入此流中的数据都被放入到此buffer中。

无参或者使用一个可选的初始化buffer的大小的参数构造。

一般将其和FilterOutputStream套接得到额外的功能。建议首先和BufferedOutputStream

套接实现缓冲功能。通过toByteArray方法可以得到流中的数据。

FileOutputStream

将信息写入文件中。

使用代表文件路径的StringFile对象或者FileDescriptor对象创建。还可以加一个代表写

入的方式是否为append的标记。

一般将其和FilterOutputStream套接得到额外的功能。

PipedOutputStream

任何写入此对象的信息都被放入对应

PipedInputStream对象的缓存中,

从而完成线程的通信,实现了“管道”

的概念。具体在后面详细讲解。

利用PipedInputStream构造

在多线程程序中数据的目的地的。一般将其和FilterOutputStream套接得到额外的功能。

FilterOutputStream

实现装饰器功能的抽象类。为其它

OutputStream对象增加额外的功能。

见下表

见下表

在FilterOutputStream类下还有一些具体的子类,如下图所示。


功能

如何构造

怎样使用

ByteArrayOutputStream

在内存中创建一个buffer。所有写

入此流中的数据都被放入到此buffer中。

无参或者使用一个可选的初始化buffer的大小的参数构造。

一般将其和FilterOutputStream套接得到额外的功能。建议首先和BufferedOutputStream

套接实现缓冲功能。通过toByteArray方法可以得到流中的数据。

FileOutputStream

将信息写入文件中。

使用代表文件路径的StringFile对象或者FileDescriptor对象创建。还可以加一个代表写

入的方式是否为append的标记。

一般将其和FilterOutputStream套接得到额外的功能。

PipedOutputStream

任何写入此对象的信息都被放入对应

PipedInputStream对象的缓存中,

从而完成线程的通信,实现了“管道”

的概念。具体在后面详细讲解。

利用PipedInputStream构造

在多线程程序中数据的目的地的。一般将其和FilterOutputStream套接得到额外的功能。

FilterOutputStream

实现装饰器功能的抽象类。为其它

OutputStream对象增加额外的功能。

见下表

见下表

3、字符输入流

1.Reader是所有的输入字符流的父类,它是一个抽象类。

2.CharReaderStringReader是两种基本的介质流,它们分别将Char数组、String中读取数据。PipedReader是从与其它线程共用的管道中读取数据。

3. BufferedReader很明显就是一个装饰器,它和其子类负责装饰其它Reader对象。

4.FilterReader是所有自定义具体装饰流的父类,其子类PushbackReaderReader对象进行装饰,会增加一个行号。

5.InputStreamReader是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream转变为Reader的方法。我们可以从这个类中得到一定的技巧。





4、字符输出流



在上面的关系图中可以看出:

1.Writer是所有的输出字符流的父类,它是一个抽象类。

2. CharArrayWriterStringWriter是两种基本的介质流,它们分别向Char数组、String中写入数据。PipedWriter是向与其它线程共用的管道中写入数据,

3. BufferedWriter是一个装饰器为Writer提供缓冲功能。

4.PrintWriterPrintStream极其类似,功能和使用也非常相似。

5.OutputStreamWriterOutputStreamWriter转换的桥梁,它的子类FileWriter其实就是一个实现此功能的具体类(具体可以研究一下Source Code)。功能和使用和OutputStream极其类似,后面会有它们的对应图。



区别:

Reader和Writer要解决的,最主要的问题就是国际化。原先的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上百实例源码以及开源项目源代码

     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...

    JAVA上百实例源码以及开源项目

     Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...

    java开源包8

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包10

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包1

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包7

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包11

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包6

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包9

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包4

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包101

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包5

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包3

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java范例开发大全(pdf&源码)

    第7章 输入/输出流(教学视频:116分钟) 152 7.1 文件和目录 152 实例116 显示文件的基本信息 152 实例117 显示目录的基本信息 153 实例118 在指定的目录下创建单个文件 156 实例119 在指定的目录下创建多个临时...

    疯狂JAVA讲义

    第1章 Java概述 1 1.1 Java语言的发展简史 2 1.2 Java的竞争对手及各自优势 4 1.2.1 C#简介和优势 4 1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6...

    java开源包2

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    Java资源包01

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    Java典型模块

    第12章 捉迷藏游戏(事件) 12.1 捉迷藏游戏原理 12.1.1 项目结构框架分析 12.1.2 项目功能业务分析 12.2 捉迷藏游戏的实现过程 12.2.1 捉迷藏游戏项目的原理 12.2.2 自定义按钮类 12.2.3 测试的类 12.3 知识点扩展...

Global site tag (gtag.js) - Google Analytics