流提供对二进制内容的最直接访问,因此任何InputStream/OutputStream实现始终在ints和bytes上操作。
// 从流中读取一个字节 int b = inputStream.read(); if (b >= 0) { // 负值表示流的结尾,正常值的范围是0-255 // 将字节写入另一个流 outputStream.write(b); } // 读取大块 byte[] data = new byte[1024]; int nBytesRead = inputStream.read(data); if (nBytesRead >= 0) { // 负值表示流结束 // 将块写入另一个流 outputStream.write(data, 0, nBytesRead); }
有一些例外,可能最显着的例外是PrintStream添加了“方便地打印各种数据值的表示形式的能力”。这允许使用诸如之类的方法System.out同时用作二进制InputStream和文本输出。System.out.println()
此外,某些流实现还用作与更高级别内容(例如Java对象(请参见序列化)或本机类型,例如DataOutputStream/)的接口DataInputStream。
通过Writer和Reader类,Java还提供了用于显式字符流的API。尽管大多数应用程序将这些实现基于流,但是字符流API并未公开任何二进制内容的方法。
// 本示例使用平台的默认字符集,请参见下文 // 为了更好的实施。 Writer writer = new OutputStreamWriter(System.out); writer.write("你好,世界!"); 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();
最常用的ReadersBufferedReader提供了一种从另一台阅读器读取整行文本的方法,并且可能是逐行读取字符流的最简单方法:
// 从baseReader读取,一次一行 BufferedReader reader = new BufferedReader( baseReader ); String line; while((line = reader.readLine()) != null) { // 切记:System.out是流,不是编写器! System.out.println(line); }