Stream vs WriterReader API
Streams 提供对二进制内容的最直接访问,因此任何 InputStream
/ OutputStream
实现始终在 int
s 和 byte
s 上运行。
// Read a single byte from the stream
int b = inputStream.read();
if (b >= 0) { // A negative value represents the end of the stream, normal values are in the range 0 - 255
// Write the byte to another stream
outputStream.write(b);
}
// Read a chunk
byte[] data = new byte[1024];
int nBytesRead = inputStream.read(data);
if (nBytesRead >= 0) { // A negative value represents end of stream
// Write the chunk to another stream
outputStream.write(data, 0, nBytesRead);
}
有一些例外,可能最值得注意的是 PrintStream
增加了方便地打印各种数据值表示的能力。这允许使用 System.out
作为二进制 InputStream
并使用诸如 System.out.println()
之类的方法作为文本输出。
此外,一些流实现用作更高级内容的接口,例如 Java 对象(请参阅序列化)或本机类型,例如 DataOutputStream
/ DataInputStream
。
通过 Writer
和 Reader
类,Java 还为显式字符流提供 API。虽然大多数应用程序都将这些实现基于流,但字符流 API 不会公开任何二进制内容的方法。
// This example uses the platform's default charset, see below
// for a better implementation.
Writer writer = new OutputStreamWriter(System.out);
writer.write("Hello world!");
Reader reader = new InputStreamReader(System.in);
char singleCharacter = reader.read();
每当需要将字符编码为二进制数据时(例如,当使用 InputStreamWriter
/ OutputStreamWriter
类时),如果你不想依赖于平台的默认字符集,则应指定字符集。如有疑问,请使用与 Unicode 兼容的编码,例如所有 Java 平台都支持的 UTF-8。因此,你应该远离像 FileWriter
和 FileReader
这样的类,因为那些总是使用默认的平台字符集。使用字符流访问文件的更好方法是:
Charset myCharset = StandardCharsets.UTF_8;
Writer writer = new OutputStreamWriter( new FileOutputStream("test.txt"), myCharset );
writer.write('Ä');
writer.flush();
writer.close();
Reader reader = new InputStreamReader( new FileInputStream("test.txt"), myCharset );
char someUnicodeCharacter = reader.read();
reader.close();
最常用的 Reader
之一是 BufferedReader
,它提供了一种从另一个读取器读取整行文本的方法,并且可能是逐行读取字符流的最简单方法:
// Read from baseReader, one line at a time
BufferedReader reader = new BufferedReader( baseReader );
String line;
while((line = reader.readLine()) != null) {
// Remember: System.out is a stream, not a writer!
System.out.println(line);
}