Java Writer
Java Writer类(java.io.Writer
)是Java IO API中所有Writer
子类的基类。书写器类似于输出流,不同之处在于它基于字符而不是基于字节。换句话说," Writer"用于写文本,而" OutputStream"则用于写原始字节。
Unicode中的字符
如今,许多应用程序都使用Unicode(通常为UTF-8或者UTF-16)来存储文本数据。在UTF-8中,可能需要一个或者多个字节来表示单个字符。在UTF-16中,每个字符用2个字节表示。要正确编写UTF-8或者UTF-16,我们需要知道要使用两种格式中的哪一种来存储文本,并且需要知道如何使用所选格式正确地编码字符。
这是JavaWriter
类派上用场的地方。 JavaWriter
子类通常可以为我们处理UTF-8和UTF-16编码,因此我们不必为此担心。
Writer子类
通常,我们将直接使用Writer
子类,而不是直接使用Writer
。 Writer的子类包括OutputStreamWriter,CharArrayWriter,FileWriter以及许多其他子类。这是JavaWriter
子类的列表:
- FileWriter
- OutputStreamWriter
- BufferedWriter
- PipedWriter
- CharArrayWriter
- FilterWriter
- StringWriter
- PrintWriter
Writer和目的地
Java"Writer"通常连接到数据的某个目标,例如文件,字符数组,网络套接字等。这在Java IO概述文本中也有更详细的说明。
write(int)
Java Writer的write(int)方法将int的低16位作为单个字符写入到Writer所连接到的目的地。这是将单个字符写入JavaWriter
的示例:
Writer writer = new FileWriter("data/output.txt"); writer.write('A');
write(char [])
JavaWriter
还具有write(char [])
方法,该方法可以将字符数组写入到Writer
连接的目标位置。 write(char [])方法返回实际写入Writer的字符数。这是一个将字符数组写入JavaWriter
的示例:
Writer writer = new FileWriter("data/output.txt"); char[] chars = new char[]{'A','B','C','D','E'}; writer.write(chars);
写入性能
向Java Writer中写入字符数组比一次写入一个字符要快。高达10倍甚至更高的加速比可能是非常显着的。因此,建议尽可能使用write(char [])方法。
我们获得的确切速度取决于运行Java代码的计算机的基础操作系统和硬件。加速取决于诸如内存速度,硬盘速度和缓冲区大小,或者网卡速度和缓冲区大小之类的问题,具体取决于"写入器"将数据发送到哪个目的地。
通过BufferedWriter进行透明缓冲
通过将其包装在Java BufferedWriter中,可以获得对写入JavaWriter
的字节的透明缓冲。写入" BufferedWriter"的所有字节将首先在" BufferedWriter"的内部字节数组内进行缓冲。当缓冲区已满时,立即将缓冲区全部刷新到底层的" Writer"。这是将JavaWriter
包装在BufferedWriter
中的示例:
int bufferSize = 8 * 1024; Writer writer = new BufferedWriter( new FileWriter("c:\data\output-file.txt"), bufferSize );
我们可以在我的BufferedWriter教程中阅读有关BufferedWriter
的更多信息。
flush()
JavaWriter
的flush()
方法将所有写入Writer
的数据刷新到基础数据目标。例如,如果"作家"是"文件作家",则写入"文件作家"的字节可能尚未完全写入磁盘。即使Java代码已将数据写入" FileWriter",数据也可能会缓存在OS内存中的某个位置。通过调用flush()
,我们可以确保所有缓冲的数据都将被刷新(写入)到磁盘(或者网络,或者Writer
的目的地具有的其他任何对象)中。这是一个通过调用JavaWriter
的flush()
方法刷新数据的示例:
writer.flush();
关闭Writer
完成将字符写入JavaWriter
后,我们应该将其关闭。我们可以通过调用close()
方法来关闭Writer
。这是关闭JavaWriter
的示例:
Writer writer = new FileWriter("c:\data\output-text.txt"); while(hasMoreCharacters()) { int character = getNextCharacter(); writer.write(character); } writer.close();
省略了hasMoreCharacters()和getNextCharacter()的具体实现,但是对于理解本示例的原理而言,它们并不是真正重要的。重要的是,一旦" while"循环结束,并且我们完成了将数据写入" Writer"的操作,便会调用其" close()"方法,该方法将关闭" Writer"。
上面的示例并不完全可靠。万一write()
方法抛出异常,将永远不会调用close()
方法。异常将使程序退出上述代码所在的任何方法。
相反,我们应该使用带有资源构造的Java try来关闭Writer
。这是一个使用try-with-resources构造关闭JavaWriter
的示例:
try( Writer writer = new FileWriter("c:\data\output-text.txt")) { while(hasMoreCharacters()) { int character = getNextCharacter(); writer.write(character); } }
一旦退出" try"块,由于" Writer"在" try"块的括号内声明,因此将自动调用" Writer"的" close()"方法。即使从try块内部抛出异常,在将异常传播到调用堆栈之前,仍会调用close()方法。