【Java】IO

从文件中读取内容,向文件中写入内容,截短文件、合并文 件、压缩文件……,诸如此类的操作,称为文件存取操作, 主要使用“流(Stream)”来完成

与文件操作相关的类,集中于java.io包中。

Java 1.4中加入了一个New I/O API,提供了一些类完成文件和流操作。

Java 7中又加入了一些新类型,称为NIO.2,NIO.2中最重要的是引入了PathAutoCloseable接口,还有一个Files类,它的静态方法封装了文件的常用操作。

File类

Java使用File类来统一操作文件和文件夹。

  • java.io.File代表与平台无关的文件或目录。也就是说可以通过File类在Java程序中操作文件或目录;
  • File类只能用来操作文件或目录(包括新建、删除、重命名文件和目录等操作),但不能用来访问文件中的内容;
  • 如果需要访问文件中的内容,则需要使用输入/输出流。

RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。RandomAccessFile类支持“随机访问”方式,这里“随机”是指可以跳转到文件的任意位置处读写数据。 在访问一个文件的时候,不必把文件从头读到尾,而是希望像访问一个数据库一样“随心所欲”地访问一个文件的某个部分,这时使用类就是最佳选择。‎ RandomAccessFile对象类有个位置指示器‎‎,指向当前读写处的位置,当前读写n个字节后,文件指示器将指向这n个字节后面的下一个字节处。 刚打开文件时,文件指示器指向文件的开头处,可以移动文件指示器到新的位置,随后的读写操作将从新的位置开始。 类在数据等长记录格式文件的随机(相对顺序而言)读取时有很大的优势,但该类仅限于操作文件,不能访问其他的I/O设备,如网络、内存映像等。

IO Stream

分类

  • 根据操作数据类型(能用记事本打开并能看到其中的字符内容的是文本文件,反之是二进制文件

    • 字节流:二进制,以字节为单位

      字节流的两个基类 InputStream和OutputStream

      凡是以InputStream或OutputStream结尾的类型为字节流

    • 字符流:文本,以字符(2个字节)为单位

      字符流的两个基类 Reader和Writer

      凡是以Reader或Writer结尾的均为字符流

    • 区别

      • 字节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法;
      • 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节;
      • 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据;
  • 根据流向

    • 输入流
    • 输出流
  • 根据具体功能

    • 节点流:以从或向一个特定的地方(节点)读写数据。

      1、文件: FileInputStreamFileOutputStreamFileReaderFileWriter 文件进行处理的节点流;   

      2、字符串: StringReaderStringWriter 对字符串进行处理的节点流;   

      3、数组: ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组);   

      4、管道: PipedInputStreamPipedOutputStreamPipedReaderPipedWriter对管道进行处理的节点流;   

      5、基类: InputStreamOutputStreamReaderWriter

    • 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

      1、缓冲流:BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter  增加缓冲功能,避免频繁读写硬盘。   

      2、转换流:InputStreamReaderOutputStreamReader实现字节流和字符流之间的转换。   

      3、数据流 DataInputStreamDataOutputStream等提供将基础数据类型写入到文件中,或者读取出来。

img

img

关闭流

流关闭的原则:先打开先关闭;如果A依赖B,则先关闭A再关闭B;对于处理流如果将节点流关闭以后再关闭处理流,会抛出IO异常,所以直接关闭处理流就行了,会自动调用关闭里面节点流的方法。

注意

  • 如果将节点流关闭以后再关闭处理流,会抛出IO异常
  • 如果关闭了处理流,在关闭与之相关的节点流,也可能出现IO异常。

InputStream

img

ByteArrayInputStream:字节数组输入流,它的内部缓冲区就是一个字节数组,该类的功能就是从字节数组(byte[])中进行以字节为单位的读取资源文件;

PipedInputStream:管道字节输入流,它和PipedOutputStream一起使用,能实现**多线程间的管道通信。**多线程管道通信的主要流程是在一个线程中向PipedOutputStream写入数据,这些数据会自动传送到对应的管道输入流PipedInputStream中,其他线程通过读取PipeInputStream中缓冲的数据实现多线程间通信;

FilterInputStream :过滤输入流,装饰者模式中处于装饰者,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流的,也就是处理类。常见的子类有DataInputStreamBufferedInputStream

BufferedInputStream:缓冲输入流,由于基础输入流一个字节一个字节读取,频繁与磁盘进行交互,造成读取速度较低.缓冲流的存在就是先将数据读取到缓冲流(内存中),然后一次性从内存中读取多个字符.提高读取的效率;

DataInputStream:数据输入流,以机器无关的方式读取Java的基本类型;

FileInputSream:文件输入流,它通常用于对文件进行读取操作;

File:对指定目录的文件进行操作。注意,该类虽然是在IO包下,但是并不继承自四大基础类;

ObjectInputStream:对象输入流,用来提供对“基本数据或对象”的持久存储。通俗点讲,也就是能直接传输对象(反序列化中使用)。

OutputStream

img

ByteArrayOutputStream:字节数组输出流,它的内部缓冲区就是一个字节数组,该类的功能就是从字节数组(byte[])中进行以字节为单位的写入资源文件;

PipedOutputStream :管道字节输出流,它和PipedInputStream一起使用,能实现多线程间的管道通信。

FilterOutputStream :过滤输出流,装饰者模式中处于装饰者,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流的,也就是处理类。常见的子类有DatOutputStreamBufferedOutputStream

BufferedOutputStream:缓冲输出流,由于基础输入流一个字节一个字节写入,频繁与磁盘进行交互,造成读取速度较低.缓冲流的存在就是先将数据写入到缓冲流(内存中),然后一次性从内存中写入多个字符.提高读取的效率;

DataOutputStream:数据输出流,以机器无关的方式读取Java的基本类型;

PrintStream:继承了FilterOutputStream。是"装饰类"的一种,所以属于字节流体系中(与PrintStream相似的流PrintWriter继承于Writer,属于字符流体系中),为其他的输出流添加功能.使它们能够方便打印各种数据值的表示形式;

FileOutputStream :文件输出流,它通常用于对文件进行写入操作;

ObjectOutputStream :对象输出流,用来提供对“基本数据或对象”的持久存储。通俗点讲,也就是能直接传输对象(反序列化中使用),和所有FilterOutputStream 的子类都是装饰流(序列化中使用)。

Reader

img

CharArrayReader :字符数组输入流。它和ByteArrayInputStream类似,只不过ByteArrayInputStream是字节数组输入流,而CharArray是字符数组输入流

PipedReader:管道字符流, 是从与其它线程共用的管道中读取数据。

FilterReader:过滤输入字符流, 是所有自定义具体装饰流的父类,为所有装饰类提供一个标准、只是简单重写了父类Reader的所有方法、要求子类必须重写核心方法、和提供具有自己特色的方法、这里没有像字节流那样有很多的子类来实现不同的功能、可能是因为字符流本来就是字节流的一种装饰、所以在这里没有必要再对其进行装饰、只是提供一个扩展的接口而已;

BufferedReader:缓冲字符流, 为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率;

InputStreamReader是一个连接字节流和字符流的桥梁,它将字节流转变为字符流;

FileReader:继承InputStreamReader,可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有ReaderInputStream 的对应关系。

Writer

img

CharArrayWriterStringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。

PipedWriter 是向与其它线程共用的管道中写入数据 BufferedWriter 是一个装饰器为Writer 提供缓冲功能。

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

OutputStreamWriterOutputStreamWriter 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类。功能和使用和OutputStream 极其类似。

转换流

4.1、定义:字符和字节直接的转换,是字符流和字节流之间的桥梁,文本文件在硬盘中以字节流的形式存储时,通过InputStreamReader读取后转化为字符流给程序处理,即可对读取到的字节数据经过指定编码转换成字符;程序处理的字符流通过OutputStreamWriter转换为字节流保存,即可对读取到的字符数据经过指定编码转换成字节。

4.2、何时使用转换流?

①当字节和字符之间有转换动作时; ②流操作的数据需要编码或解码时。

4.3、具体的对象体现:

InputStreamReader:字节到字符的桥梁 OutputStreamWriter:字符到字节的桥梁 这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来,即:

InputStreamReader(InputStream in):将字节流以字符流输入。

OutputStreamWriter(OutStreamout):将字节流以字符流输出。

System.in and System.out

System.inSystem.out分别代表了系统标准的输入和输出设备 默认输入设备是:键盘,输出设备是:显示器 System.in的类型是InputStream System.out的类型是PrintStream

对象流

ObjectInputStream和OjbectOutputSteam用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。

  • 序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
  • 反序列化:用ObjectInputStream类读取基本类型数据或对象的机制

ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量

总结

InputStream类的功能不足被Scanner解决了

OutputStream类的功能不足被PrintStream解决了

Reader类功能不足被BufferReader解决了

Writer类的功能不足被PrintWriter解决了

输出数据用printStreamprintwriter读取数据用Scanner其次是bufferReader

NIO

java.nio全称java non-blocking IO,是指jdk1.4 及以上版本里提供的新api(New IO) ,为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络。

Licensed under CC BY-NC-SA 4.0
Last updated on Jan 05, 2022 00:00 UTC
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy