JAVA基础1-JAVA IO学习笔记

初级篇

InputStream

结构图

在这里插入图片描述

具体类

InputStream抽象类,定义了read、mark、reset、close方法。并未真正实现内容。其中的mark(标记mark值)和reset(将当前pos设置为mark)方法只有子类ByteArrayInputStream、BufferedInputStream和PushbackInputStream实现具体方法。

FileInputStream继承InputStream抽象类,具体实现read、close方法(具体调用的是native的方法)。

ObjectInputStream继承InputStream抽象类并实现ObjectInput接口,对对象的读操作,而对象必须实现Serializable接口。除了实现read、close方法外,还实现readLong、readShort、readFloat、readChar等java继承类型的方法,另外readObject则是调用对象的toString方法。。其内部实现实际是采用DataInputStream的方法。

ByteArrayInputStream继承InputStream抽象类,对一个数据的byte进行读操作。除了实现read、close方法外,还实现mark、rest方法。入参是一个数据的byte。

PipedInputStream继承InputStream抽象类,对一个数据的byte进行操作,默认大小是1024。此类用于线程之间信息发送,一般与PipedOutStream配对使用。有2个重要方法。第一个connect方法,设置输入的PipedOutStream;第二个receive方法,用于接收PipedOutStream的输入,即PipedOutStream的write最后是调用PipedInputStream的receive。

FilterInputStream继承抽象类,使用装饰者模式的设计一些特殊功能的InputStream。

DataInputStream继承FilterInputStream类,是InputStream的修饰者,主要增加java基础类型的读操作。如:readLong、readShort、readFloat、readChar等。

BufferedInputStream继承FilterInputStream类,是InputStream的修饰者,入参为InputStream,主要增加缓存功能。

PushbackInputStream继承FilterInputStream类,是InputStream的修饰者,主要增加unread方法,实现回写效果。

SequenceInputStream继承InputStream抽象类,实现多个InputStream的操作,可以同时初始化多个InputStream,然后依次读取。

StringBufferInputStream继承InputStream抽象类,入参为String。此类已经作废。

OutputStream

结构图

在这里插入图片描述

具体类

OutputStream抽象类,定义了write、flush、close方法。并未真正实现内容。

FileOutputStream继承OutputStream抽象类,构造函数的入参可以说File或者文件名,具体实现write、close方法(具体调用的是native的方法)。

ObjectOutputStream继承OutputStream抽象类并实现ObjectOutput接口,对对象的写操作,而对象必须实现Serializable接口。除了实现write、flush、close方法外,还实现readLong、writeShort、writeFloat、writeChar等java继承类型的方法,另外writeObject则是调用对象的toString方法。。其实现通过采用内部类BlockataOutputStream的方法,内部类实际采用DataOutputStream的操作。

ByteArrayOutputStream继承OutputStream抽象类,对一个数据的byte进行写操作。除了实现write、close方法外,还实现mark、rest方法。入参是一个数据的byte。

PipedOutputStream继承OutputStream抽象类,对一个数据的byte进行操作,默认大小是1024。此类用于线程之间信息发送,一般与PipedInputStream配对使用。增加一个connect方法,设置输入的PipedInputStream。

FilterOutputStream继承抽象类,使用装饰者模式的设计一些特殊功能的OutputStream。

DataOutputStream继承FilterOutputStream类,是OutputStream的修饰者,主要增加java基础类型的读操作。如:writeLong、writeShort、writeFloat、writeChar等。

BufferedOutputStream继承FilterOutputStream类,是OutputStream的修饰者,主要增加缓存功能。

PrintStream继承FilterOutputStream类,是OutputStream的修饰者,主要增加unwrite方法,实现写到控制台功能。主要通过BufferedWriter来实现功能。增加print等一些功能。

Reader

结构图

在这里插入图片描述

具体类

Reader抽象类,定义read、mark、reset、close方法,并未实现具体方法。其中mark、reset方法只有子类StringReader、BufferReader、CharArrayReader和PushbackReader实现。

InputStreamReader继承Reader抽象类,使用InputStream和编码作为入参,通过StreamDecoder进行编码转换(字节转字符)实现read、mark、close方法。增加getEncoding返回获取编码。

FileReader继承InputStreamReader抽象类,使用File作为入参,实际创建FileInputStream并将其传入StreamDecoder。

StringReader继承Reader抽象类,使用String作为入参,主要对入参的String进行操作。同时实现mark和reset方法。

PipedReader继承Reader抽象类,对一个数组的char进行操作,默认大小是1024。此类用于线程之间信息发送,一般与PipedWriter配对使用。增加一个connect方法,设置输入的PipedWriter。

BufferReader继承Reader抽象类,入参是Reader。实现缓存效果。增加一个重要的方法readLine,一行数据写入。

CharArrayReader继承Reader抽象类,对一数组的char进行操作,入参为数组的char。同时实现mark和reset方法。

FilterReader继承抽象类,使用装饰者模式的设计一些特殊功能的Reader。

PushbackReader继承FilterReader类,是Reader的修饰者,主要增加unread方法,实现回写效果。

Writer

结构图

在这里插入图片描述

具体类

Writer抽象类,定义write、flush、close方法,并未实现具体方法。

InputStreamWriter继承Writer抽象类,使用OutputStream和编码作为入参,通过StreamEncoder进行编码转换(字节转字符)实现write、flush、close方法。增加flushBuffer刷新缓存。

FileWriter继承OutputStreamWriter抽象类,使用File作为入参,实际创建FileOutputStream并将其传入StreamEncoder。

StringWriter继承Writer抽象类,主要对StringBuffer进行操作。

PipedWriter继承Writer抽象类,对一个数组的char进行操作,默认大小是1024。此类用于线程之间信息发送,一般与PipedWriter配对使用。增加一个connect方法,设置输入的PipedWriter。

BufferedWriter继承Writer抽象类,入参是Writer。实现缓存效果。增加一个重要的方法newLine,换行功能。

CharArrayWriter继承Writer抽象类,对一数组的char进行操作,入参为数组的char。同时实现mark和reset方法。

PrintWriter继承Writer抽象类,主要通过PrintStream进行对控制台输出。

FilterWriter继承抽象类,使用装饰者模式的设计一些特殊功能的Writer。目前暂未有装饰者。

高级篇

Java.nio与java.io的区别。

  1. 提高的读写速度,原先的io是阻塞型的,nio是将I/O交个操作系统,这样更适合与并发操作。
  2. 数据的打包和传输方式,原先io是采用流方式,而nio是采用缓冲区方式。
  3. selector的作用,运行一个线程使用多个通道。

具体类

RandomAccessFile

实现DataOutput, DataInput接口。实际上与inputstream和outputstream无关系。作为一个可以同时实现读写文件的操作。主要实现seek、skipBytes方法用于操作文件位置,同时实现length( )、getFilePointer( )获取一些文件属性。此接口将逐渐被NIO取代。

Channel

通道类似流,但又有些不同:

  1. 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
  2. 通道可以异步地读写。
  3. 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
    这些是Java NIO中最重要的通道的实现:
  4. FileChannel 从文件中读写数据。
  5. DatagramChannel 能通过UDP读写网络中的数据。
  6. SocketChannel 能通过TCP读写网络中的数据。
  7. ServerSocketChannel可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

Buffer

Java NIO中的Buffer用于和NIO通道进行交互。数据是从通道读入缓冲区,从缓冲区写入到通道中的。

使用Buffer读写数据一般遵循以下四个步骤:

  1. 写入数据到Buffer
  2. 调用flip()方法
  3. 从Buffer中读取数据
  4. 调用clear()方法或者compact()方法

Buffer的capacity,position和limit

  1. capacity
    作为一个内存块,Buffer有一个固定的大小值,也叫“capacity”.你只能往里写capacity个byte、long,char等类型。一旦Buffer满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据。
  2. position
    当你写数据到Buffer中时,position表示当前的位置。初始的position值为0.当一个byte、long等数据写到Buffer后, position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity – 1.
    当读取数据时,也是从某个特定位置读。当将Buffer从写模式切换到读模式,position会被重置为0. 当从Buffer的position处读取数据时,position向前移动到下一个可读的位置。
  3. limit
    在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。 写模式下,limit等于Buffer的capacity。
    当切换Buffer到读模式时, limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。换句话说,你能读到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)

Java NIO 有以下Buffer类型

  1. ByteBuffer
  2. MappedByteBuffer
  3. CharBuffer
  4. DoubleBuffer
  5. FloatBuffer
  6. IntBuffer
  7. LongBuffer
  8. ShortBuffer

Scatter/Gather

分散(scatter)从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。
聚集(gather)写入Channel是指在写操作时将多个buffer的数据写入同一个Channel,因此,Channel 将多个Buffer中的数据“聚集(gather)”后发送到Channel。
FileChannel
实现ByteChanel的抽象类。Java NIO中的FileChannel是一个连接到文件的通道。可以通过文件通道读写文件。FileChannel无法设置为非阻塞模式,它总是运行在阻塞模式下。增加一些特殊方法,比如:size、truncat、force等方法。

SocketChannel

实现ByteChanel的抽象类。Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel:第一种是打开一个SocketChannel并连接到互联网上的某台服务器;第二种是一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。增加一些特殊方法,比如:connect、bind、socket等方法。

ServerSocketChannel

实现ByteChanel的抽象类。Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样。ServerSocketChannel类在 java.nio.channels包中。增加一些特殊方法,比如:connect、bind、accept、socket等方法。

DatagramChannel

实现ByteChanel的抽象类。Java NIO中的DatagramChannel是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数据包。

Pipe

Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。主要用于线程间的操作。

IO的同步异步和阻塞非阻塞

流程

在这里插入图片描述
流程描述:应用进程在调用IO(无论是磁盘还是网络IO),会线程从用户状态切换成内核状态。调用recv确认数据是否准备完成,如果未准备好,则一直等到。当数据准备好,就复制数据到用户空间,返回成功,并切换回用户状态。
等待数据时间:当内核没有准备好数据,线程等待数据准备完成的时间。(阻塞/非阻塞)
复制数据到用户空间的时间:内核缓存的数据复制到用户空间。(同步/异步)

阻塞

在这里插入图片描述
当应用进程调用recv时,发现没有数据时,一直等待,则是阻塞IO。

非阻塞

在这里插入图片描述
当系统调用recv时,发现没有数据就返回,过一段时间继续调用recv确认,这样就在等待数据时,用户进程可以做其它事情。这种模式称为非阻塞IO。

IO复用模型

在这里插入图片描述
应用进程先调用select、poll或者epoll,确认是否数据已完成,但是这个过程是阻塞的,只是没有阻塞recv。从这个角度,这样就在等待数据时,用户进程可以做其它事情,可以称为非阻塞IO。

信号驱动模型

在这里插入图片描述
应用进程先调用sigaction注册信号函数,注册到内核。当数据准备好时,内核会执行信号函数(里面包含recv)。这样就在等待数据时,用户进程可以做其它事情。所以这种模式也称为非阻塞IO。

异步IO模型

在这里插入图片描述
应用进程调用aio_read就即可返回,让内核自己等待数据完成,当完成时,内核还负责复制数据到用户空间,再通知应用进程。这个过程,复制数据的过程应用进程都不需要等待的,我们称为异步IO。当然,这个也是非阻塞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值