关于 java.io.ObjectInputStream.BlockDataInputStream 的部分笔记,该类是ObjectInputStream的底层数据读取类,用来完成从流中读取数据的所有操作。本文演示代码段的执行环境基于JDK版本1.7。
概述
BlockDataInputStream有两个读取模式:默认模式中,输入数据按照和DataOutputStream一样的格式被写入,如果在块数据模式中,输入数据被块数据标记包围写入。是否采用缓存支持取决于读取模式,默认模式不会采用缓存机制来获取数据,所有数据直接从底层输入流获取。反之,如果是块数据模式那么数据会被缓存下来供以后读取需要。
继承关系
1 | // BlockDataInputStream |
实现接口
类名 | 实现接口 |
---|---|
BlockDataInputStream | Closeable, DataInput, AutoCloseable |
BlockDataInputStream
Constructor Summary
public ObjectInputStream(InputStream in)
1 | BlockDataInputStream(InputStream in) { |
根据指定输入流初始化一个底层输入流和一个DataInputStream实例。块数据模式默认被置为false。
部分方法
boolean setBlockDataMode(boolean newmode)
1 | boolean setBlockDataMode(boolean newmode) throws IOException { |
设置块数据读取模式,true为on,false为off,并返回设置之前的读取模式值。如果在模式从on到off的切换过程中尚有数据需要读取,那么就抛出IllegalStateException异常。
boolean getBlockDataMode()
1 | boolean getBlockDataMode() { |
获取块数据读取模式。
void skipBlockData()
1 | void skipBlockData() throws IOException { |
跳过当前数据块到达当前数据块的结尾位置。如果当前模式不是on,那么抛出异常。refill()方法完成实际的跳过操作。
private void refill()
1 | private void refill() throws IOException { |
用块数据重新填充内部缓冲区buffer。在方法被调用时,buffer中存在的数据被认为是消费过的。新的pos,end,unread字段被认为是新的块数据信息。操作流程如图1所示:
private int readBlockHeader(boolean canBlock)
1 | private int readBlockHeader(boolean canBlock) throws IOException { |
尝试读取下一个块数据的头部信息,并返回头部指定的块数据长度。
int currentBlockRemaining()
1 | int currentBlockRemaining() { |
返回当前数据块中剩余的可读数据长度。如果是块数据模式,那么就返回剩余长度,否则抛出异常。
int peek()
1 | int peek() throws IOException { |
获取(但不会消费掉)下一个字节的内容。如果是块数据模式,那么尝试从底层缓冲区buffer中取数据,否则直接调用底层输入流获取。
byte peekByte()
1 | byte peekByte() throws IOException { |
获取(但不会消费掉)下一个字节的内容,内容以字节类型返回。
public int read()
1 | public int read() throws IOException { |
获取下一个字节的内容。如果是块数据模式,那么尝试从底层缓冲区buffer中取数据,否则直接调用底层输入流获取。
public int read(byte[] b, int off, int len)
1 | public int read(byte[] b, int off, int len) throws IOException { |
获取字节内容,并存储到字节数组b中自off位置起,长度为len的空间内。返回实际读取的字符内容长度。
int read(byte[] b, int off, int len, boolean copy)
1 | int read(byte[] b, int off, int len, boolean copy) throws IOException { |
如果是块数据读取模式,尝试从底层缓冲区buffer中获取数据。如果copy为true,那么首先将读取的数据保存到底层缓冲区buffer中,然后在将数据返回到b中。如果不是快数据读取模式,那么直接从底层输入流获取数据。
public long skip(long len)
1 | public long skip(long len) throws IOException { |
跳过当前块数据中长度为len的内容。
public int available()
1 | public int available() throws IOException { |
返回当前块数据中剩余可读的数据量。
public void close()
1 | public void close() throws IOException { |
关闭当前底层输入流。
primitive data input methods
1 | /* ----------------- primitive data input methods ------------------ */ |
primitive data array input methods
1 | /* -------------- primitive data array input methods --------------- */ |
String readLongUTF()
1 | String readLongUTF() throws IOException { |
读取并返回以长UTF格式写入流中的字符串。长UTF格式有别于标准的UTF格式,因为长UTF格式采用8个比特位作为头部来传输UTF编码长度,而标准UTF只有两个比特位。
private String readUTFBody(long utflen)
1 | private String readUTFBody(long utflen) throws IOException { |
读取并返回UTF编码除了头部之外的数据内容。
private long readUTFSpan(StringBuilder sbuf, long utflen)
1 | private long readUTFSpan(StringBuilder sbuf, long utflen) throws IOException { |
private int readUTFChar(StringBuilder sbuf, long utflen)
1 | private int readUTFChar(StringBuilder sbuf, long utflen) throws IOException { |
PeekInputStream
1 | private static class PeekInputStream extends InputStream { |
涉及基础知识点
- NIL
参考文献
- NIL