-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7e0b20d
commit b2e8eb9
Showing
5 changed files
with
383 additions
and
0 deletions.
There are no files selected for viewing
92 changes: 92 additions & 0 deletions
92
openjdk/notes/openjdk/jdk/src/share/classes/java/io/BufferedWriter.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# OpenJDK 源码阅读之 BufferedWriter | ||
|
||
标签(空格分隔): 源代码阅读 Java 封神之路 | ||
|
||
--- | ||
|
||
## 概要 | ||
|
||
* 类继承关系 | ||
|
||
```java | ||
java.lang.Object | ||
java.io.Writer | ||
java.io.BufferedWriter | ||
``` | ||
|
||
* 定义 | ||
|
||
```java | ||
public class BufferedWriter | ||
extends Writer | ||
``` | ||
|
||
* 要点 | ||
|
||
增加了缓冲功能,要写入的数据,不会立即写入,而会先放在缓冲区,待缓冲区满,或者调用 `flush` 时,一次写入,以提升效率。另外,还添加了 `newLine` 函数。 | ||
|
||
|
||
## 实现 | ||
|
||
|
||
* 构造器 | ||
|
||
```java | ||
public BufferedWriter(Writer out) { | ||
this(out, defaultCharBufferSize); | ||
} | ||
``` | ||
|
||
需要一个底层的流,用于写入数据,还需要指定缓冲区大小,默认是 `8192`。 | ||
|
||
|
||
```java | ||
public BufferedWriter(Writer out, int sz) { | ||
super(out); | ||
if (sz <= 0) | ||
throw new IllegalArgumentException("Buffer size <= 0"); | ||
this.out = out; | ||
cb = new char[sz]; | ||
nChars = sz; | ||
nextChar = 0; | ||
|
||
lineSeparator = java.security.AccessController.doPrivileged( | ||
new sun.security.action.GetPropertyAction("line.separator")); | ||
} | ||
``` | ||
|
||
初始化时,会保存好底层流,并生成缓冲区,指定好当前写入数据的位置,另外,还需要获取行分割符号,因为不同系统的行分割符号是不一样的。 | ||
|
||
|
||
* write | ||
|
||
```java | ||
public void write(int c) throws IOException { | ||
synchronized (lock) { | ||
ensureOpen(); | ||
if (nextChar >= nChars) | ||
flushBuffer(); | ||
cb[nextChar++] = (char) c; | ||
} | ||
} | ||
``` | ||
|
||
需要写入的数据,放在缓冲区 `cb` 中,如果缓冲区满,就调用 `flushBuffer` 写入。 | ||
|
||
* flushBuffer | ||
|
||
```java | ||
void flushBuffer() throws IOException { | ||
synchronized (lock) { | ||
ensureOpen(); | ||
if (nextChar == 0) | ||
return; | ||
out.write(cb, 0, nextChar); | ||
nextChar = 0; | ||
} | ||
} | ||
``` | ||
|
||
刷新缓冲区时,会调用底层流的 `write` 函数,具体怎么写入,就要看底层流的 `write` 是如何实现的了。 | ||
|
||
|
88 changes: 88 additions & 0 deletions
88
openjdk/notes/openjdk/jdk/src/share/classes/java/io/CharArrayWrite.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# OpenJDK 源码阅读之 CharArrayWrite | ||
|
||
标签(空格分隔): 源代码阅读 Java 封神之路 | ||
|
||
--- | ||
|
||
## 概要 | ||
|
||
* 类继承关系 | ||
|
||
```java | ||
java.lang.Object | ||
java.io.Writer | ||
java.io.CharArrayWriter | ||
``` | ||
|
||
* 定义 | ||
|
||
```java | ||
public class CharArrayWriter | ||
extends Writer | ||
``` | ||
|
||
* 要点 | ||
|
||
将数据写入字符数组中,可以通过 `toCharArray`,`toString` 得到这个数组,数组大小会自动扩充。 | ||
|
||
|
||
## 实现 | ||
|
||
* 数组 | ||
|
||
```java | ||
protected char buf[]; | ||
``` | ||
|
||
字符会被写入到这样一个数组内。 | ||
|
||
|
||
* 构造器 | ||
|
||
默认情况下,这个数组大小为 32 | ||
|
||
|
||
```java | ||
public CharArrayWriter() { | ||
this(32); | ||
} | ||
|
||
public CharArrayWriter(int initialSize) { | ||
if (initialSize < 0) { | ||
throw new IllegalArgumentException("Negative initial size: " | ||
+ initialSize); | ||
} | ||
buf = new char[initialSize]; | ||
} | ||
``` | ||
|
||
* write | ||
|
||
```java | ||
public void write(int c) { | ||
synchronized (lock) { | ||
int newcount = count + 1; | ||
if (newcount > buf.length) { | ||
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount)); | ||
} | ||
buf[count] = (char)c; | ||
count = newcount; | ||
} | ||
} | ||
``` | ||
|
||
`write` 时,会将数据写入 `buf` 数组里,如果数组满了,会调用 `Arrays.copyOf` 扩充,并复制数据,生成新的数组。 扩充策略是现有大小翻倍。 | ||
|
||
* toCharArray | ||
|
||
```java | ||
public char toCharArray()[] { | ||
synchronized (lock) { | ||
return Arrays.copyOf(buf, count); | ||
} | ||
} | ||
``` | ||
|
||
`toCharArray` 会把内部数组复制一份,而不是直接返回内部的数组。 | ||
|
||
|
77 changes: 77 additions & 0 deletions
77
openjdk/notes/openjdk/jdk/src/share/classes/java/io/OutputStreamWrite.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# OpenJDK 源码阅读之 OutputStreamWrite | ||
|
||
标签(空格分隔): 源代码阅读 Java 封神之路 | ||
|
||
--- | ||
|
||
## 概要 | ||
|
||
* 类继承关系 | ||
|
||
```java | ||
java.lang.Object | ||
java.io.Writer | ||
java.io.OutputStreamWriter | ||
``` | ||
|
||
* 定义 | ||
|
||
```java | ||
public class OutputStreamWriter | ||
extends Writer | ||
``` | ||
|
||
* 要点 | ||
|
||
这个类根据 charset 将字节流转化成字符流。 | ||
|
||
|
||
## 实现 | ||
|
||
* 编码器 | ||
|
||
```java | ||
private final StreamEncoder se; | ||
``` | ||
|
||
这是此类的核心,所有操作,都会用这个编码器完成。 | ||
|
||
* 构造器 | ||
|
||
```java | ||
public OutputStreamWriter(OutputStream out, String charsetName) | ||
throws UnsupportedEncodingException | ||
{ | ||
super(out); | ||
if (charsetName == null) | ||
throw new NullPointerException("charsetName"); | ||
se = StreamEncoder.forOutputStreamWriter(out, this, charsetName); | ||
} | ||
``` | ||
|
||
构造函数可以指定 `charset` 的名字,同一个字节流,如果编码方式不同,转化出的字符就不同,所以,需要指定 `charset`,然后,通过 `StreamEncoder.forOutputStreamWriter` 得到编码器。如果没有指定: | ||
|
||
```java | ||
public OutputStreamWriter(OutputStream out) { | ||
super(out); | ||
try { | ||
se = StreamEncoder.forOutputStreamWriter(out, this, (String)null); | ||
} catch (UnsupportedEncodingException e) { | ||
throw new Error(e); | ||
} | ||
} | ||
``` | ||
|
||
在 `charsetName` 的参数位置上,会传入空,`forOutputStreamWriter` 会寻找系统的相应设置,如果找不到,会被设置为 `UTF-8`。 | ||
|
||
* write | ||
|
||
```java | ||
public void write(int c) throws IOException { | ||
se.write(c); | ||
} | ||
``` | ||
|
||
调用的是编码器的 `write`,它会将 `c` 按照 charset 编码,然后写入。`write` 背后最终的编码函数是一个 `native` 函数。 | ||
|
||
其它函数,如 `flush, close` 都是调用 `se` 的相应函数实现的。 |
70 changes: 70 additions & 0 deletions
70
openjdk/notes/openjdk/jdk/src/share/classes/java/io/StringBuffer.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# OpenJDK 源码阅读之 StringBuffer | ||
|
||
标签(空格分隔): 源代码阅读 Java 封神之路 | ||
|
||
--- | ||
|
||
## 概要 | ||
|
||
* 类继承关系 | ||
|
||
```java | ||
java.lang.Object | ||
java.io.Writer | ||
java.io.StringWriter | ||
``` | ||
|
||
* 定义 | ||
|
||
```java | ||
public class StringWriter | ||
extends Writer | ||
``` | ||
|
||
* 要点 | ||
|
||
将数据写入一个 string 缓冲区内,当需要时,会转化成 string,听起来很像 CharArrayWriter 啊,不知道有什么不同。 | ||
|
||
|
||
## 实现 | ||
|
||
* 内部缓冲 | ||
|
||
```java | ||
private StringBuffer buf; | ||
``` | ||
|
||
内部是使用 `StringBuffer` 保存写入的数据的。 | ||
|
||
|
||
* 构造器 | ||
|
||
```java | ||
public StringWriter() { | ||
buf = new StringBuffer(); | ||
lock = buf; | ||
} | ||
``` | ||
|
||
初始化时,会生成 `StringBuffer` 对象,并设置锁,由于多个线程共同操作此对象时,会共享 buf ,所以锁就在 buf 上。 | ||
|
||
|
||
* write | ||
|
||
```java | ||
public void write(int c) { | ||
buf.append((char) c); | ||
} | ||
``` | ||
|
||
`write` 就是调用了 `StringBuffer` 的 `append` 函数,不过从这里看,也没有使用锁啊。。不过,`append` 函数本身就是带有 `synchronized` 关键字的。 | ||
|
||
另外,这个类还提供了写入 string 功能。 | ||
|
||
```java | ||
public void write(String str) { | ||
buf.append(str); | ||
} | ||
``` | ||
|
||
似乎是在类中,为 `StringBuffer` 的一些方法提供了相应的接口。 |
56 changes: 56 additions & 0 deletions
56
openjdk/notes/openjdk/jdk/src/share/classes/java/io/Writer.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# OpenJDK 源码阅读之 Writer | ||
|
||
标签(空格分隔): 源代码阅读 Java 封神之路 | ||
|
||
--- | ||
|
||
## 概要 | ||
|
||
* 类继承关系 | ||
|
||
```java | ||
java.lang.Object | ||
java.io.Writer | ||
``` | ||
|
||
* 定义 | ||
|
||
```java | ||
public abstract class Writer | ||
extends Object | ||
implements Appendable, Closeable, Flushable | ||
``` | ||
|
||
* 要点 | ||
|
||
写入字符流的抽象类,其子类必需实现 `write(char[], int, int), flush(), and close()`,另外,也会添加或者覆盖其它方法,以提升效率或增加功能。 | ||
|
||
|
||
## 实现 | ||
|
||
* write | ||
|
||
```java | ||
public void write(int c) throws IOException { | ||
synchronized (lock) { | ||
if (writeBuffer == null){ | ||
writeBuffer = new char[writeBufferSize]; | ||
} | ||
writeBuffer[0] = (char) c; | ||
write(writeBuffer, 0, 1); | ||
} | ||
} | ||
``` | ||
|
||
注意,会用一个 `writeBuffer` 保存要写入的数据,然后调用 `write(char[], int, int)` 写入数据,这个函数是个抽象函数,具体实现由子类完成。 | ||
|
||
另外两个子类需要实现的函数是: | ||
|
||
```java | ||
abstract public void flush() throws IOException; | ||
abstract public void close() throws IOException; | ||
``` | ||
|
||
|
||
|
||
|