zoukankan      html  css  js  c++  java
  • 深入分析Java I/O的工作机制 (一)

    此篇博客看至许令波的深入分析javaWeb内幕书籍, 此篇博客写的是自己看完之后理解的重点内容,加一些理解,希望对你有帮助。

    1.Java的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操作,也就是将什么样的数据写到什么地方的问题。

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

    基于字节的I/O操作接口输入和输出分别是InputStream和OutputStream

    InputStream的类层次结构图(OutputStream,Writer和Reader的类层次结构图和InputStream差不多都是有很多子类可以实现不同的功能,他们的子类也相仿。):

    看到这个结构图其实只想说明两点,一是操作数据的方式可以组合使用的,如这样组合:

      

     OutputStream outputStream=new FileOutputStream("");//OutputStream可以new他的子类用于实现不同的作用。

    小tip:父类作为接收类型,去new子类,称为向上转型。   子类作为接收类型,去new父类,称为向下转型。

     OutputStream outputStream=new FileOutputStream("");//父类 new子类  向上转型
         BufferedOutputStream bufferedOutputStream= new  FileOutputStream("");//子类new父类  向下转型

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

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

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

    Writer类提供了一个抽象方法write(char cbuf[], int off, int len)。

    abstract public void write(char cbuf[], int off, int len) throws IOException;

    Reader也提供了一个抽象方法read(char cbuf[], int off, int len),返回读到的n个字节数,不管是Writer耗时Reader类,它们都只定义了读取或写入的数据字符的方式也就是怎么写或读,但是并没有规定数据要写在哪里,这些内容就是后面要讨论的基于磁盘和网络的工作机制。

    abstract public int read(char cbuf[], int off, int len) throws IOException;

    1.3字节与字符的转化接口

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

    InputStreamReader类是从字节到字符的转化桥梁,

     

     从InputStream到Reader的过程要指定编码字符集,否则将采用默认系统的字符集,很可能出现乱码问题。StreamDecoder正是完成从字节到字符的解码的实现类。

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

    写入也是类似的过程:

     

    通过OutputStreamWriter类完成了从字节的编码过程,由StreamEncoder完成编码过程。

    小tip:

    Ctrl+H 显示类结构图

    Ctrl+O 查看这个类的所有方法

    Ctrl+鼠标左键点击    进入这个类

    因为这个有点长,我还没看完I/O的工作机制所以只先发出这一段,以后再发所有,  告辞 。

  • 相关阅读:
    用小程序·云开发两天搭建mini论坛丨实战
    巧用小程序·云开发实现邮件发送功能丨实战
    借助云开发,10行代码实现小程序支付功能!丨实战
    你的心事我全知晓——心情日记小程序丨实战
    只需20小时,让0基础的你掌握小程序云开发!这个暑假,约否?
    诗词歌赋,样样精通!诗词古语小程序带你领略魅力古风丨实战
    在线教育项目-day02【后台讲师管理模块】
    在线教育项目-day02【搭建项目结构】
    在线教育项目-day01【wrapper条件构造器】
    在线教育项目-day01【性能分析插件】
  • 原文地址:https://www.cnblogs.com/java-263/p/10264931.html
Copyright © 2011-2022 走看看