开发过程中,想彻底掌握Java-IO类库,带你深入源码,一击即中!

ByteArrayInputStream 支持从 byte 数组读取数据,通过构造函数可以指定该 byte 数组:

protected byte buf[];

protected int pos;

protected int mark = 0;

protected int count;

public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}

public ByteArrayInputStream(byte buf[], int offset, int length) {
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.mark = offset;
}

ObjectInputStream

ObjectInputStream 与 DataInputStream 类似也支持 Java 基本类型的读取,此外还支持反序列化读取对象。它常常与 ObjectOutputStream 搭配使用。因此,ObjectOutputStream 实现将基本类型或者对象序列化并输出到 IO 字节流或者设备上,而 ObjectInputStream 从 IO 字节流或者设备上反序列化读取基本类型或者对象。

比如,从文件中读取一个 person 对象。

ObjectInputStream input = new ObjectInputStream(new FileInputStream(“data.txt”));
Person person = (MyClass) input.readObject();
input.close();

这里要求 Person 一定要实现 java.io.Serializable 接口。

PipedInputStream

PipedInputStream 通常和 PipedOutputStream 搭配使用,实现了一个承载字节流的管道类。PipedOutputStream 的输出会自动调用 PipedInputStream 的 receive 方法作为输入。PipedInputStream 提供了以下几个特殊方法:

// 连接 PipedOutputStream 对象,形成管道
public void connect(PipedOutputStream src) throws IOException;
// 接收一个字节
protected synchronized void receive(int b) throws IOException;
// 接收一个字节数组
synchronized void receive(byte b[], int off, int len) throws IOException;

注意到其 read 方法和 receive 都是同步方法,read 方法在没有数据的时候会发生阻塞,而 receive 方法在缓冲数组没有剩余空间的时候也会发生阻塞:

public synchronized int read() throws IOException {
if (!connected) {
throw new IOException(“Pipe not connected”);
} else if (closedByReader) {
throw new IOException(“Pipe closed”);
} else if (writeSide != null && !writeSide.isAlive()
&& !closedByWriter && (in < 0)) {
throw new IOException(“Write end dead”);
}

readSide = Thread.currentThread();
int trials = 2;
while (in < 0) {
// in小于0表示缓冲数组为空,处于无数据状态
if (closedByWriter) {
/* closed by writer, return EOF /
return -1;
}
if ((writeSide != null) && (!writeSide.isAlive()) && (–trials < 0)) {
throw new IOException(“Pipe broken”);
}
/
might be a writer waiting /
notifyAll();
try {
// 阻塞等待
wait(1000);
} catch (InterruptedException ex) {
throw new java.io.InterruptedIOException();
}
}
int ret = buffer[out++] & 0xFF;
if (out >= buffer.length) {
out = 0;
}
if (in == out) {
/
now empty */
in = -1;
}

return ret;
}

protected synchronized void receive(int b) throws IOException {
checkStateForReceive();
writeSide = Thread.currentThread();
if (in == out)
// 当in等于out,意味着缓冲数组已满,阻塞等待空间释放
awaitSpace();
if (in < 0) {
in = 0;
out = 0;
}
buffer[in++] = (byte)(b & 0xFF);
if (in >= buffer.length) {
in = 0;
}
}

SequenceInputStream

SequenceInputStream 支持将多个 InputStream 组合起来,并按照顺序进行读取。

OutputStream

OutputStream 与 InputStream 相对应,实现上存在很多相似之处。先看看内部方法:

public abstract class OutputStream implements Closeable, Flushable {
public abstract void write(int b) throws IOException;
public void write(byte b[]) throws IOException {//}
public void write(byte b[], int off, int len) throws IOException {/
/}
public void flush() throws IOException {//}
public void close() throws IOException {/
/}
}

OutputStream 实现了 Closeable 接口和 Flushable 方法,同样有一个抽象的 write 方法需要实现。其他方法提供框架性代码,也需要实现类覆写相关方法,提供更多的自定义功能。

FileOutputStream

实现上与 FileInputStream 类似,提供对文件写入字节流的功能。

FilterOutputStream

与 FilterInputStream 类似,对 OutputStream 对象进行包装,并继承了 OutputStream 并覆写全部方法,方法内容都是简单地调用内部的 OutputStream 对象。

同样的也有几个子类实现:

  • BufferedOutputStream:带缓冲区的字节流输出类,与 BufferedInputStream 对应;
  • DataOutputStream:提供写 Java 基本类型相关方法的字节流类,与 DataInputStream 对应;
  • PrintStream:与 DataOutputStream 有些类似,不过它提供了更加丰富的写出方法,并且支持换行输出。
ByteArrayOutputStream

与 ByteArrayInputStream 相反,ByteArrayOutputStream 实现输出到内部的缓存字节数组 buf 中。特有的方法有:

/** 将该 Stream 输出为 byte 数组**/
public synchronized byte toByteArray()[] {
return Arrays.copyOf(buf, count);
}
/** 将该 Stream 输出到另一个 Stream 上**/
public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
}

ObjectOutputStream

与 ObjectInputStream 对应,ObjectOutputStream 实现将 Java 基本类型数据或者 Java 对象序列化后写入输出字节流中。

PipedOutputStream

与 PipedInputStream 搭配使用,PipedOutputStream 会输出字节流到管道另一端的 PipedInputStream。

字符流

字节流处理的是 byte 数组,而字符流处理的是 char 数组。而且字符流相关的类都以 Reader 或者 Writer 为后缀。

Reader

先看看内部方法:

public abstract class Reader implements Readable, Closeable {
public int read(java.nio.CharBuffer target) throws IOException;
public int read() throws IOException;
public int read(char cbuf[]) throws IOException;
abstract public int read(char cbuf[], int off, int len) throws IOException;
public long skip(long n) throws IOException;
public boolean ready() throws IOException;
public boolean markSupported();
public void mark(int readAheadLimit) throws IOException;
public void reset() throws IOException;
abstract public void close() throws IOException;
}

内部方法与 InputStream 非常相似,同样实现类需要实现 read 方法。

BufferedReader

带缓冲区的 Reader 实现。

CharArrayReader

从字符数组读取数据的 Reader 实现。

InputStreamReader

InputStreamReader 是一个包装类,内部对象是 StreamDecoder。StreamDecoder 支持从 InputStream 中读取字符。

public class InputStreamReader extends Reader {

private final StreamDecoder sd;

/**

  • Creates an InputStreamReader that uses the default charset.

  • @param in An InputStream
    */
    public InputStreamReader(InputStream in) {
    super(in);
    try {
    sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
    } catch (UnsupportedEncodingException e) {
    // The default encoding should always be available
    throw new Error(e);
    }
    }
    // …
    }

  • FileReader:InputStreamReader 的实现,入参是一个 FileInputStream 对象

public FileReader(String fileName) throws FileNotFoundException {
super(new FileInputStream(fileName));
}

FilterReader

FilterReader 与上文的 FilterInputStream 类似,也是一个包装类。它内部包含一个 Reader 对象,并且继承自 Reader 并覆写所有方法,而方法内容都是简单调用内部 Reader 对象。

  • PushbackReader:FilterReader 的实现类,内部使用一个 buf 字符数组对已读数据进行缓存,然后可以通过 unread 方法将已读的数据重新放回 buf 数组,从而实现了一个支持 push back 的字符流类。
PipedReader

与 PipedInputStream 类似

StringReader

与 CharArrayReader 类似

Writer

BufferedWriter

带缓冲区的 Writer 实现。

CharArrayWriter

与 CharArrayReader 相反,CharArrayWriter 将数据写入内部字符数组中。其特有方法有:

public char toCharArray()[] {
synchronized (lock) {
return Arrays.copyOf(buf, count);
}
}

public void writeTo(Writer out) throws IOException {
synchronized (lock) {
out.write(buf, 0, count);
}
}

OutputStreamWriter

与 InputStreamReader 相对,OutputStreamWriter 也是一个包装类,内部对象是 StreamEncoder。StreamEncoder 支持将字符输出到 OutputStream 中。

  • FileWriterOutputStreamWriter 的实现,入参是一个 FileOutputStream 对象

public FileWriter(String fileName) throws IOException {
super(new FileOutputStream(fileName));
}

FilterWriter

FilterWriter 的是一个包装类,内部包含一个 Writer 对象,同时也继承了 Writer,并覆写了部分方法。这个类在 JDK 里没有找到相关实现子类。

PipedWriter

与 PipedReader PipedWriter 会输出字符流到管道另一端的 PipedWriter。

PrintWriter

类似 PrintStream,提供了丰富的写出方法,并且支持换行输出。这里发现其并没有实现 FilterWriter,这点与 PrintStream 的继承结构并不吻合。个人觉得这点不是很好,但是也无伤大雅。

StringWriter

将字符流输出到内部的 StringBuffer 上,同时可以通过 toString 方法获取内部的字符串缓存:

public String toString() {
return buf.toString();
}

其他

RandomAccessFile

FileInputStream(文件字符流)或 FileReader(文件字节流)来读文件都只能够实现从文件开始顺序读取到文件结束。

而 RandomAccessFile 可以实现随机读写,用来只读取文件中的一部分:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后:学习总结——MyBtis知识脑图(纯手绘xmind文档)

学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。下方即为我手绘的MyBtis知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的MyBtis知识脑图原件(包括上方的面试解析xmind文档)

image

除此之外,前文所提及的Alibaba珍藏版mybatis手写文档以及一本小小的MyBatis源码分析文档——《MyBatis源码分析》等等相关的学习笔记文档,也皆可分享给认可的朋友!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
Btis知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的MyBtis知识脑图原件(包括上方的面试解析xmind文档)

[外链图片转存中…(img-Axy7Ta5f-1713672728918)]

除此之外,前文所提及的Alibaba珍藏版mybatis手写文档以及一本小小的MyBatis源码分析文档——《MyBatis源码分析》等等相关的学习笔记文档,也皆可分享给认可的朋友!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值