简体   繁体   English

DataOutputStream#writeBytes(String)vs BufferedWriter #write(String)

[英]DataOutputStream#writeBytes(String) vs BufferedWriter#write(String)

I would like to create a HTML file for my report. 我想为我的报告创建一个HTML文件。 The content in the report can be created either by using BufferedWriter#write(String) 可以使用BufferedWriter#write(String)创建报表中的内容

File f = new File("source.htm");
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
bw.write("Content");

or by using DataOutputStream#writeBytes(String) 或者使用DataOutputStream#writeBytes(String)

File f = new File("source.htm");
DataOutputStream dosReport = new DataOutputStream(new FileOutputStream(f)); 
dosReport.wrtiteBytes("Content");

Is one of them better than the other? 其中一个比另一个好吗? Why is it so? 为什么会这样?

If you're writing out text then you should use a Writer , which handles the conversion from unicode characters (Java's internal representation of strings) into an appropriate character encoding such as UTF-8. 如果您正在写出文本,那么您应该使用Writer ,它处理从unicode字符(Java的字符串内部表示)到适当的字符编码(如UTF-8)的转换。 DataOutputStream.writeBytes simply outputs the low-order eight bits of each char in the string and ignores the high-order eight bits entirely - this is equivalent to UTF-8 for ASCII characters with codes below 128 (U+007F and below) but almost certainly wrong for anything beyond ASCII. DataOutputStream.writeBytes只输出字符串中每个char的低8位并完全忽略高位8位 - 这相当于代码低于128(U + 007F及以下)的ASCII字符的UTF-8,但几乎相同除了ASCII以外的任何东西都是错

Rather than a FileWriter, you should use an OutputStreamWriter so you can select a specific encoding (FileWriter always uses the platform's default encoding, which varies from platform to platform): 您应该使用OutputStreamWriter而不是FileWriter,因此您可以选择特定的编码(FileWriter始终使用平台的默认编码,该编码因平台而异):

File f = new File("source.htm");
BufferedWriter bw = new BufferedWriter(
  new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
bw.write("Content");

Firstly, the DataOutputStream in your 2nd example serves no useful purpose 1 . 首先,第二个示例中的DataOutputStream没有用处1 Indeed, if your Strings contain characters that don't fit into 8 bits, the writeBytes(String) method is going to mangle the text. 实际上,如果你的字符串包含不符合8位的字符,则writeBytes(String)方法将破坏文本。 Get rid of it. 摆脱它。 The Data streams are designed for reading and writing fine-grained binary data. 数据流设计用于读取和写入细粒度二进制数据。 For plain bytes, use a plain (or buffered) Input or Output stream. 对于普通字节,请使用普通(或缓冲)输入或输出流。

Secondly, in this specific use-case where you writing the entire output is a single write operation, the BufferedWriter doesn't add any value either. 其次,在这个特定的用例中,您编写整个输出是单个写操作,BufferedWriter也不会添加任何值。

So in this case. 所以在这种情况下。 you should be comparing: 你应该比较:

    File f = new File("source.htm");
    Writer w = new FileWriter(f);
    w.write("Content");

versus

    File f = new File("source.htm");
    OutputStream os = new FileOutputStream(f); 
    os.write("Content".getBytes());

To my mind, the first version looks simpler and cleaner. 在我看来,第一个版本看起来更简单,更清洁。 And it is best to use the Reader and Writer stacks for text I/O ... because that's what they were designed for. 最好将ReaderWriter堆栈用于文本I / O ......因为这就是它们的设计目的。 (They take care of the encoding and decoding issues, cleanly and transparently.) (他们干净透明地处理编码和解码问题。)

You could benchmark them if you really need to know which is faster (on your system!) but I suspect there is not a lot of difference ... and that the first version is faster. 你可以对它们进行基准测试,如果你真的需要知道哪个更快(在你的系统上!)但是我怀疑它没有太大区别......而且第一个版本更快。

1 - I think DataOutputStream has buffering under the covers, but for this use-case, buffering does not help performance. 1 - 我认为DataOutputStream具有缓冲功能,但对于此用例,缓冲无助于提高性能。


In use-cases where you are performing multiple (small) writes instead of on big one, there is a significant performance advantage in using a BufferedWriter (or a BufferedOutputStream ) instead of an unbuffered writer or stream. 在您执行多个(小)写的,而不是在一个大的使用情况,存在使用一个显著的性能优势BufferedWriter (或BufferedOutputStream ),而不是一个缓冲的作家或流。


The other point is that both versions of your code is using the platform's default character encoding to encode the output file. 另一点是,您的代码的两个版本都使用平台的默认字符编码来编码输出文件。 It may be more appropriate to use a specific encoding independently of the default, or make this a configuration or command line parameter. 独立于默认值使用特定编码可能更合适,或者将其设置为配置或命令行参数。

OutputStream: 的OutputStream:

This abstract class is the superclass of all classes representing an output stream of bytes. 此抽象类是表示输出字节流的所有类的超类。 An output stream accepts output bytes and sends them to some sink. 输出流接受输出字节并将它们发送到某个接收器。

Applications that need to define a subclass of OutputStream must always provide at least a method that writes one byte of output. 需要定义OutputStream子类的应用程序必须始终至少提供一个写入一个输出字节的方法。

For example: 例如:

OutputStream os = new FileOutputStream("test.txt");

BufferedWriter 但是BufferedWriter

Writes text to a character-output stream, buffering characters so as to provide for the efficient writing of single characters, arrays, and strings. 将文本写入字符输出流,缓冲字符,以便有效地写入单个字符,数组和字符串。 The buffer size may be specified, or the default size may be accepted. 可以指定缓冲区大小,或者可以接受默认大小。 The default is large enough for most purposes. 对于大多数用途,默认值足够大。

A newLine() method is provided, which uses the platform's own notion of line separator as defined by the system property line.separator. 提供了一个newLine()方法,它使用平台自己的行分隔符概念,由系统属性line.separator定义。 Not all platforms use the newline character ('\\n') to terminate lines. 并非所有平台都使用换行符('\\ n')来终止行。 Calling this method to terminate each output line is therefore preferred to writing a newline character directly. 因此,调用此方法终止每个输出行比直接编写换行符更为可取。

In general, a Writer sends its output immediately to the underlying character or byte stream. 通常,Writer会立即将其输出发送到基础字符或字节流。 Unless prompt output is required, it is advisable to wrap a BufferedWriter around any Writer whose write() operations may be costly, such as FileWriters and OutputStreamWriters . 除非需要提示输出,否则建议将BufferedWriter包装在任何write()操作可能代价高昂的Writer周围,例如FileWritersOutputStreamWriters

For example: 例如:

 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM