java.io.Writerクラスのソースコードを取り上げる。まず目につくのが,writeBufferというbyte配列のバッファが用意されていることである。バッファリングを行っている。そしてその大きさは1024となっている。
続いて,Readerクラスの場合と同様にnullWriterという何を出力してもどこにも出力しない「ブラックホール」のようなWriterクラスが実装されている。
そして,中段にはlockというObject型のロックオブジェクトがあり,排他制御に用いられている。コンストラクタはprotectedのものが2種類定義されている。
このクラスの本質的な機能を果たすwrite()メソッドは多数オーバーロードされている。これらのメソッドはいずれも抽象メソッドであるwrite(char cbuf[], int off, int len)を呼び出す。
- public void write(int c) throws IOException
- public void write(char cbuf[]) throws IOException
- public void write(String str) throws IOException
- public void write(String str, int off, int len) throws IOException
このほかにReaderクラスにはないものとして,バッファにコンテンツを追加するためのappend()メソッドやバッファの内容をストレージ等に書き込むためのflush()メソッドが定義されている。
/*
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.Objects;
public abstract class Writer implements Appendable, Closeable, Flushable {
private char[] writeBuffer;
private static final int WRITE_BUFFER_SIZE = 1024;
public static Writer nullWriter() {
return new Writer() {
private volatile boolean closed;
private void ensureOpen() throws IOException {
if (closed) {
throw new IOException("Stream closed");
}
}
@Override
public Writer append(char c) throws IOException {
ensureOpen();
return this;
}
@Override
public Writer append(CharSequence csq) throws IOException {
ensureOpen();
return this;
}
@Override
public Writer append(CharSequence csq, int start, int end) throws IOException {
ensureOpen();
if (csq != null) {
Objects.checkFromToIndex(start, end, csq.length());
}
return this;
}
@Override
public void write(int c) throws IOException {
ensureOpen();
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
Objects.checkFromIndexSize(off, len, cbuf.length);
ensureOpen();
}
@Override
public void write(String str) throws IOException {
Objects.requireNonNull(str);
ensureOpen();
}
@Override
public void write(String str, int off, int len) throws IOException {
Objects.checkFromIndexSize(off, len, str.length());
ensureOpen();
}
@Override
public void flush() throws IOException {
ensureOpen();
}
@Override
public void close() throws IOException {
closed = true;
}
};
}
protected Object lock;
protected Writer() {
this.lock = this;
}
protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
public void write(int c) throws IOException {
synchronized (lock) {
if (writeBuffer == null){
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
writeBuffer[0] = (char) c;
write(writeBuffer, 0, 1);
}
}
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
public abstract void write(char cbuf[], int off, int len) throws IOException;
public void write(String str) throws IOException {
write(str, 0, str.length());
}
public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
if (len <= WRITE_BUFFER_SIZE) {
if (writeBuffer == null) {
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
cbuf = writeBuffer;
} else { // Don't permanently allocate very large buffers.
cbuf = new char[len];
}
str.getChars(off, (off + len), cbuf, 0);
write(cbuf, 0, len);
}
}
public Writer append(CharSequence csq) throws IOException {
write(String.valueOf(csq));
return this;
}
public Writer append(CharSequence csq, int start, int end) throws IOException {
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
public Writer append(char c) throws IOException {
write(c);
return this;
}
public abstract void flush() throws IOException;
public abstract void close() throws IOException;
}
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.io;
import java.util.Objects;
public abstract class Writer implements Appendable, Closeable, Flushable {
private char[] writeBuffer;
private static final int WRITE_BUFFER_SIZE = 1024;
public static Writer nullWriter() {
return new Writer() {
private volatile boolean closed;
private void ensureOpen() throws IOException {
if (closed) {
throw new IOException("Stream closed");
}
}
@Override
public Writer append(char c) throws IOException {
ensureOpen();
return this;
}
@Override
public Writer append(CharSequence csq) throws IOException {
ensureOpen();
return this;
}
@Override
public Writer append(CharSequence csq, int start, int end) throws IOException {
ensureOpen();
if (csq != null) {
Objects.checkFromToIndex(start, end, csq.length());
}
return this;
}
@Override
public void write(int c) throws IOException {
ensureOpen();
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
Objects.checkFromIndexSize(off, len, cbuf.length);
ensureOpen();
}
@Override
public void write(String str) throws IOException {
Objects.requireNonNull(str);
ensureOpen();
}
@Override
public void write(String str, int off, int len) throws IOException {
Objects.checkFromIndexSize(off, len, str.length());
ensureOpen();
}
@Override
public void flush() throws IOException {
ensureOpen();
}
@Override
public void close() throws IOException {
closed = true;
}
};
}
protected Object lock;
protected Writer() {
this.lock = this;
}
protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
public void write(int c) throws IOException {
synchronized (lock) {
if (writeBuffer == null){
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
writeBuffer[0] = (char) c;
write(writeBuffer, 0, 1);
}
}
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
public abstract void write(char cbuf[], int off, int len) throws IOException;
public void write(String str) throws IOException {
write(str, 0, str.length());
}
public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
if (len <= WRITE_BUFFER_SIZE) {
if (writeBuffer == null) {
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
cbuf = writeBuffer;
} else { // Don't permanently allocate very large buffers.
cbuf = new char[len];
}
str.getChars(off, (off + len), cbuf, 0);
write(cbuf, 0, len);
}
}
public Writer append(CharSequence csq) throws IOException {
write(String.valueOf(csq));
return this;
}
public Writer append(CharSequence csq, int start, int end) throws IOException {
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
public Writer append(char c) throws IOException {
write(c);
return this;
}
public abstract void flush() throws IOException;
public abstract void close() throws IOException;
}