I/O问题是任何编程语言都无法回避的问题,可以说I/O问题是整个人机交互的核心问题,因为I/O是机器获取和交换信息的主要渠道,在当今这个数据大爆炸时代,I/O问题尤为突出,很容易成为一个性能瓶颈。正因如此,java在I/O上也一直在做持续的优化,如从1.4版开始引入了NIO,提升I/O的性能。

java的I/O操作类在包java.io下,大概有将近80个类,这些类大概可以分成如下4组

  • 基于字节操作的I/O接口:InputStream 和 OutputStream
  • 基于字符操作的I/O接口:Writer 和 Reader
  • 基于磁盘操作的I/O接口:File
  • 基于网络操作的I/O接口:Socket

前两组主要是传输数据的数据格式,后两组主要是传输数据的方式,虽然socket类并不在java.io包下。I/O的核心问题要么是数据格式影响I/O操作,要么是传输方式影响I/O操作。I/O只是人机交互的的手段,我们除了关注功能外,还应该关注的就是如何提高它的运行效率。

基于字节的 I/O 操作接口

基于字节的I/O操作接口分别是InputStream 和OutputStream ,InputStream 的类层次结构如图所示

输入流根据数据类型和操作方式又被划分为若干子类,每个子类分别处理不同的操作类型。OutputStream 的类层次结构也类似。

这里就不详细解释每一个子类的用法了。说明两点,

一是操作数据的方式是可以组合使用的,如:

OutputStream out = new BufferedOutputStream(new ObjectOutputStream(new FileOutputStream("fileName")));

二是必须指定流最终写到什么地方,要么写到磁盘,要么写到网络中,其实从上面的层次结构中我们可以发现,写网络实际上也是写文件,只不过写网络还有一步需要处理,就是让底层操作系统再将数据传送到其他地方而不是本地磁盘。

基于字符的I/O 操作接口

不管是磁盘还是网络传输,最小的存储单元都是字节,而不是字符,所以I/O 操作的都是字节而不是字符,但是为什么有操作字符的I/O 接口呢?这是因为在我们的程序中通常操作的数据都是字符形式的,为了操作方便当然要提供一个直接写字符的I/O 接口,如此而已。我们知道从字符到字节必须经过编码转换,而这个编码又非常耗时,而且还会经常出现乱码问题,所以I/O 的编码问题经常让人头痛的问题。

如图所示是写字符的操作接口涉及的类,Writer 类提供了一个抽象方法 write(cahr cbuf[], int off, int len)。

读字符的操作接口也有类似的类结构,读字符的操作接口是 int read(cahr cbuf[] ,int off ,int len ),返回读到的n 个字节数,不管是Writer 还是 Reader 类, 它们都只定义了读取或写入的数据字符的方式,也是就怎么写或读,但是并没有规定数据要写到哪里。

字节与字符的转化接口

另外,数据持久化或网络传输都是以字节进行的,所以必须要有从字符到字节或从字节到字符的转化。从字符到字节需要转化,其中读的转化过程如图

InputStreamReader 类是从字节到字符的转化桥梁,从InputStream 到 Reader 的过程要指定编码字符集,否则将采用操作系统默认的字符集,很可能会出现乱码问题。StreamDecoder正是完成从字节到字符的解码的实现类。也就是当你用如下方式读取一个文件时:

try{
StringBuffer str = new StringBuffer();
char[] buf = new char[1024];
FileReader f = new FileReader("file");
while(f.read(buf) > 0){
str.append(buf);
}
}catch(Exception e){}

 FileReader 类就是按照上面的工作方式读取文件的,FileReader 继承了InputStreamReader类,实际上是读取文件流,然后通过StreamDecoder 解码成char ,只不过这里的解码字符集是默认字符集。

  写入也是类似的过程。

java IO 类库的基本架构的更多相关文章

  1. JAVA IO 类库详解

    JAVA IO类库详解 一.InputStream类 1.表示字节输入流的所有类的超类,是一个抽象类. 2.类的方法 方法 参数 功能详述 InputStream 构造方法 available 如果用 ...

  2. java 的IO类库的基本架构

    java IO 操作的类在java.io 包中,大概可以分为以下几组: 基于字节操作的接口:InputStream 和 OutputStream 基于字符操作的接口:Writer 和 Reader 基 ...

  3. 2.熟悉Java基本类库系列——Java IO 类库

    Java中常用的IO操作基本上可以分为四大部分,分别是:File类操作.RandomAccessFile类操作.字节流操作.字符流操作.只要熟练掌握了本文中所列举的所有例子,基本上对于Java的IO流 ...

  4. Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库

    http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...

  5. Java IO流学习

    Java IO流学习 Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是 ...

  6. 1.熟悉Java基本类库系列 - 目录

    写这个系列是想让自己多熟悉熟悉Java的基本类库,忘记的时候可以在这里看看之前写过的例子,这样就可以很快的回忆起来如何使用了. 这样就可以很节省时间了. ======= 下面是传送门啦 ======= ...

  7. 高级Java工程师必备 ----- 深入分析 Java IO (三)

    概述 Java IO即Java 输入输出系统.不管我们编写何种应用,都难免和各种输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,这要考虑的因素特别多,比如我们要考虑和哪种媒介进行IO( ...

  8. Java 的 I/O 类库的基本架构

    Java 的 I/O 类库的基本架构 I/O 问题是任何编程语言都无法回避的问题,可以说 I/O 问题是整个人机交互的核心问题,因为 I/O 是机器获取和交换信息的主要渠道.在当今这个数据大爆炸时代, ...

  9. Java I/O 工作机制(一) —— Java 的 I/O 类库的基本架构

    Java 的 I/O 类库的基本架构 Java 的 I/O 操作类在包 java.io 下,有将近 80 个类. 按数据格式分类: 面向字节(Byte)操作的 I/O 接口:InputStream 和 ...

随机推荐

  1. 多工程联编,cocopods的使用

    最近在使用coco2d-x, 想要使用 cocopods,发现我的目录结构如下图 发现我有三个工程文件,  那么 就需要多工程联编使用cocopods, workspace 'xcworkspace' ...

  2. python中将字典形式的数据循环插入Excel

    1.我们看到字典形式的数据如下所示 list=[["2891-1", "D"],["2892-1", "D"],[&qu ...

  3. 【CentOS】阿里云ECS申请CA证书配置SSL

    本文记录阿里云ECS申请CA证书流程先到阿里云控制台找到CA证书服务,这里两台ECS都已经申请签发了证书,如果是还没申请的就在"状态"中点击补全: 进去后填写完个人信息后,这里选择 ...

  4. OOAD-设计模式(一)概述

    前言 在我们很多时候设计代码都是需要用到各种不一样的设计模式的,接下来着几篇给大家领略一下设计模式.知道设计模式的作用,以及在代码的具体体现.很多时候我们看不懂代码就是因为我们不知道它使用的设计模式. ...

  5. bzoj 1705;poj 3612:[Usaco2007 Nov]Telephone Wire 架设电话线

    Description 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线. 新的电话线架设在已有的N(2 <= ...

  6. BZOJ1786: [Ahoi2008]Pair 配对/1831: [AHOI2008]逆序对

    这两道题是一样的. 可以发现,-1变成的数是单调不降. 记录下原有的逆序对个数. 预处理出每个点取每个值所产生的逆序对个数,然后dp转移. #include<cstring> #inclu ...

  7. Win10没有以太网图标如何找回?以太网适配器不见了怎么恢复?

    Win10以太网适配器不见了怎么恢复?以太网其实就是Win7系统中常说的"本地连接"假若用户发现网络适配器中的以太网适配器图标不见了,可以在设备管理器中添加一些这类适配器,具体过程 ...

  8. 修改mysql密码的四种方法

    方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...

  9. Spark算子--distinct

    distinct--Transformation类算子 代码示例    

  10. Oracle_字段数据类型

    Oracle_字段数据类型 数据库表字段的数据类型 字符数据类型 CHAR:存储固定长度的字符串 VARCHAR2 :存储可变长度的字符串 数值数据类型 NUMBER:存储整数和浮点数,格式为NUMB ...