Java I/O

作者: 黄大大吃不胖 | 来源:发表于2017-06-21 21:48 被阅读0次

Java I/O是Java中很重要的组成部分

一.以字节为向导的Stream InputStream/OutputStream

Java I/O最基本的概念就是输入流与输出流,即InputStream(输入流)和OutputStream(输出流)

InputStream

最基本的字节输入流,抽象类,定义了读取原始字节的所有基本方法

  • read() 读取一个字节的方法
  • close() 关闭stream方法,这个是每次在用完流之后必须调用的方法。
  • available() 返回stream中的可读字节数,inputstream类中的这个方法始终返回的是0,这个方法需要子类去实现。
  • skip(long n) 从stream中跳过long类型参数个位置
  • read(byte b[]) 一次性读取内容到缓冲字节数组
  • read(byte b[],int off,int len) 从数据流中的哪个位置offset开始读长度为len的内容到缓冲字节数组

下面还有三个方法:

  • mark(int readlimit) 用于标记stream的作用
  • markSupported() 返回的是boolean类型,因为不是所有的stream都可以调用mark方法的,这个方法就是用来判断stream是否可以调用mark方法和reset方法
  • reset() 这个方法和mark方法一起使用的,让stream回到mark的位置。
OutputStream

最基本的字节输出流,抽象类,定义了读取原始字节的所有基本方法

  • write(int b) 写入一个字节到stream中
  • close() 关闭流,这个是在操作完stream之后必须要调用的方法
  • flush() 这个方法是用来刷新stream中的数据,让缓冲区中的数据强制的输出
  • write(byte b[]) 写入一个byte数组到stream中
  • write(byte b[], int off, int len) 把byte数组中从offset开始处写入长度为len的数据
总结

InputStream和OutputStream定义了I/O领域最基础的行为,也就是读取和写入一个字节,同时使用了模板方法将读取和写入的行为进行了适当扩展。

扩展一:对I/O流的继承

InputStream和OutputStream都是抽象类,它们仅仅定义了I/O领域最基础的方法,但不涉及具体实现。针对不同的数据来源,InputStream和OutputStream存在三种实现:一种是基于内存的ByteArrayInputStream/ByteArrayOutputStream,一种是基于磁盘文件的FileInputStream/FileOutputStream,还有一种是基于网络的SocketInputStream/SocketOutputStream。

FileInputStream/FileOutputStream

读取写入的源是操作系统的文件使用native方法进行底层文件的读取

try  
{  
    //使用FileInputStream和FileOutputStream进行文件复制  
    FileInputStream fis=new FileInputStream("a.txt");  
    FileOutputStream fos=new FileOutputStream("b.txt");  
    int read;  
    //read=fis.read();  
    byte b[]=new byte[1024];  
    //读取文件,存入字节数组b,返回读取到的字符数,存入read,默认每次将b数组装满  
    read=fis.read(b);  
    while(read!=-1)  
    {  
        fos.write(b,0,read);  
        read=fis.read(b);  
        //read=fis.read();  
    }  
    fis.close();  
    fos.close();  
}  
catch (IOException e)  
{  
    e.printStackTrace();  
}  

ByteArrayInputStream/ByteArrayOutputStream

读取写入的源是内存的一个数组,比较少见

SocketInputStream/SocketOutputStream

读取写入远程服务器的数据流使用native方法进行底层文件的读取

除上述3种以外还有别的实现如下

StringBufferInputStream/StringBufferOutputStream

据指定串创建一个读取数据的输入流串

PipedInputStream/PipedOutputStream

实现了pipe的概念,主要在线程中使用,管道输入流是指一个通讯管道的接收端。
一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。

SequenceInputStream/SequenceOutputStream

把多个In(Out)putStream合并为一个In(Out)putStream,“序列输入(出)流”类允许应用程序把几个输入(出)流连续地合并起来,
并且使它们像单个输入(出)流一样出现。每个输入(出)流依次被读取,直到到达该流的末尾。
然后“序列输入(出)流”类关闭这个流并自动地切换到下一个输入(出)流。

扩展二:对I/O流的扩展
FilterInputStream/FilterOutputStream

FilterInputStream是InputStream一个特殊的子类,它内部有一个很重要的变量如下

protected volatile InputStream in;  

protected FilterInputStream(InputStream in) {  
    this.in = in;  
}  

这说明了FilterInputStream在实例化的时候,要传一个InputStream类的对象进来。

这个类的特殊之处,就是包含了一个InputStream,使得可以在这个InputStream基础上进行多种封装,从而达到装饰的目的。

这个类本身作用不大,但是他的子类比较有作用

DataInputStream/DataOutputStream

这两个类继承了FilterInputStream/FilterOutputStream,用来实现将java基本类型转换成二进制来进行读写操作,readInt,readFloat,readDouble...这样可以直接从stream中读取基本类型的数据

BufferedInputStream/BufferedOutputStream

继承了FilterInputStream,实现了输入流处理中的缓冲的功能。底层的流会先被读取到一个字节数组中,用户使用BufferedInputStream读取数据的时候,会先读取字节数组中的数据,读完了才会调用底层的流进行进一步的读取。这种方法可以提升读取的性能。继承了FilterOutputStream,实现了输出流处理中的缓冲功能。当用户写入数据的时候,其实是先写入到BufferedOutputStream的一个字节数组中,当这个字节数组满了,才会真正调用底层的输出流执行输出动作。这种方法可以提升写入的性能。在使用BufferedOutputStream的写入功能时,一定要使用flush,因为缓冲数组不满的时候是不会写入底层流的,在写入最后一点数据的时候,缓冲数据不一定被填满,这时候就需要调用flush进行强制刷新。

PrintStream

继承FilterOutputStream,这个类的print和println方法可以把java的一些基本类型数据转换成字节写入到底层输出流,但是PrintStream对String的转换是平台相关的,不同的平台会有不同的编码,所以写入到底层的字节也不同,因此PrintStream只适合于测试输出,不适合于一般的I/O操作,特别是网络流。

PushbackInputStream

继承了FilterInputStream,提供了一种回退的机制,可以实现unread,本质是使用缓冲数组实现了,也就是说,回退的范围是有限的。

二.以字符为向导的Stream Reader/Writer

InputStream和OutputStream是面向字节的,而人类的习惯是面向字符,因此InputStream和OutputStream对于程序猿的用户体验不是太好,于是就需要提供一些面向字符的流。由于DataInputStream/DataOutputStream在跨平台的情况下存在问题,因此,java设计者干脆仿照InputStream和OutputStream重新设计了一套面向字符的I/O,也就是Reader/Writer

Reader

基本的字符输入流,是个抽象类

方法与InputStream对应

Writer

基本的字符输出流,是个抽象类

方法与OutputStream对应

扩展一:对I/O流的继承
CharArrayReader/CharArrayWriter

与前面ByteArrayInputStream/ByteArrayOutputStream对应

StringReader/StringWriter

与前面StringBufferInputStream/StringBufferOutputStream对应

FileReader/FileWriter

与前面FileInputStream/FileOutputStream对应

PipedReader/PipedWriter

与前面PipedInputStream/PipedOutputStream对应

扩展二:对I/O流的扩展

FilterReader/FilterWriter

BufferedReader/BufferedWriter

PushbackReader

PrintWriter

三.两种不同导向的Stream之间的转换

由于计算机只识别字节,所以Reader/Writer的数据来源最终还是字节,而他们无法直接和字节打交道,这时候就需要一个中介者将Reader/Writer和InputStream和OutputStream进行打通,于是就有了InputStreamReader和OutputStreamWriter

InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。
使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。

InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。

为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader ,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

![](/Users/admin/Documents/Life/I:O/3400180-bce9503f7c9ee657.png =500x300)

相关文章

  • 线上学习资料汇总_新

    1. Java I/O 这些年一直记不住的 Java I/O 深入分析 Java I/O 的工作机制 NIO 入门...

  • NIO.2-简介

    More New I/O Java 7 中的 More New I/O APIs,通过在 java.nio.cha...

  • Java & Groovy & Scala & Kotlin -

    Overview 文章介绍的 I/O 主要用于本地文件读写,不涉及网络 I/O。 Java 篇 Java 中的 I...

  • I/O

    Java I/O 总结 理解Java中字符流与字节流的区别 深入学习 Java 序列化 Java I/O 操作及优...

  • 知识总结:I/O模型基础

    I/O基础 1、java1.4之前,java对I/O支持不完善,存在以下问题: 没有数据缓冲区,I/O性能存在问题...

  • Netty 权威指南笔记(一):网络 I/O 模型和 Java

    Netty 权威指南笔记(一):网络 I/O 模型和 Java IO 入门 Java I/O 模型的实现离不开底层...

  • Java I/O

    Java I/O主要包括三个部分1.流式部分2.非流式部分3.其他类 1.字符流 字符流处理文本数据,在java中...

  • java I/O

    一.文件/文件夹File 二.InputStream/OutputStream字节输入输出流 三.关闭流的方式 四...

  • Java I/O

    如果当初陪着你的人走远了,那些日子回忆起来会模糊吗? mark 标记reset 重置exist 存在modifie...

  • Java I/O

    流可以理解为一个有顺序的,有起点和终点的数据序列,输入流表示从一个源读取数据,输出流表示向一个目标写数据。 字节流...

网友评论

      本文标题:Java I/O

      本文链接:https://www.haomeiwen.com/subject/xttxcxtx.html