2017-04-19 43 views
0

我已经了解到,Java中的Reader和Writer更适合从文本资源读取和写入信息,而Reader/Writer是基于字符的,而流是基于字节的。 但是我遇到一个消息来源说,“有些文本是用ANSI或Unicode编码的,ANSI需要进行代码转换,而Unicode可以用UFT-8或UFT-16等不同的格式编码,因此读写器更好”。ANSI和UNICODE为什么难以使用流读取和写入文本?

做这些代码转换和不同的格式与文本资源有什么关系?因此,读者和作者能做什么使它们比处理文本的流更好?

+1

读者和作者以*字符流的形式呈现给他们的客户端,而InputStreams和OutputStreams呈现为*字节*的流。实际上,前者可以(并且必须)在内部处理字符编码,而后者则要求用户处理这些问题。作为设计原则,当您处理的数据基本上是文本(即字符)时,前者提供了更合适的抽象。 –

+2

这可能对于堆栈溢出来说过于宽泛,但是有一个很好的写法[在这里](https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-积极必须知道关于unicode和字符集没有借口/)字节流和字符流之间的区别,以及为什么有不同的编码。 – yshavit

+0

@yshavit感谢您分享此信息。 – freedev

回答

0

当java被设计时,决定将文本作为Unicode保存在java内部,所以所有脚本(比如希腊语和韩语)都可以合并。 (UTF-8)(通常为多字节,最紧凑),UTF-16 LE/BE(2字节)或甚至UTF-8 LE/BE(2字节)或甚至UTF-8编码-32。

因此内部的String .class中的常量使用UTF-8。对于UTF-16,类型char是2个字节。并且String保存了一个数组char

二进制数据,像byte[]InputStream/OutputStream可能是文本。但要将其解释为文本需要知道这些字节的编码/字符集。因此,总是会将这些字节的字节和某些字符集转换为内部Unicode(UTF-16)。

要回答这个问题,以某种方式提供二进制数据的字符集是不可避免的。这是二进制数据的缺陷。

当人们到达String, char, Reader, Writer时,已经完全使用Unicode文本。

桥接类是InputStreamReader, OutputStreamWriterFiles提供了一些很好的实用功能。

将这种情况与C进行比较,其中unsigned char可能与字节相同(或不是),并且宽字符可能可用或不可用。 Java比一些语言做得更好。但是具有C/C++背景的Java程序员决不应该使用Stringchar[]作为二进制数据:双重内存,不可撤销和损坏的转换。宁可byte[], ByteArrayOutputStream, ByteBuffer

+0

它们在内部是[UTF-16](http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.10.4)。二进制数据不具有*字符集,并且不是'二进制数据的缺陷'。 – EJP

+1

@EJP:在Java 9中,Java字符串可能在内部是ISO-8859-1(参见[JEP 254](http://openjdk.java.net/jeps/254)),如果它在内存中更紧凑UTF-16不丢失任何数据。但是,为了向后兼容,公共接口仍然必须表示UTF-16,所以对于所有意图和目的,无论内部表示如何,都将Java字符串视为UTF-16。 –

+0

@RemyLebeau我已经忘记了。谢谢。但索赔仍然是“所有Unicode都是可能的”。 ISO-8859-1是始终提供的字符集之一:StandardCharset.ISO_8859_1。这是一个有限的拉丁语-1。这是一个有价值的角落优化。当时在历史上,UTF-16字符被认为涵盖了所有可行的字符。现在,UTF-16字符可能被认为是过时的;应该考虑处理_code points_。所以是的替代编码的优点。 –

相关问题