Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 依赖默认编码,我应该使用什么,为什么?_Java_Encoding_Internationalization_Findbugs - Fatal编程技术网

Java 依赖默认编码,我应该使用什么,为什么?

Java 依赖默认编码,我应该使用什么,为什么?,java,encoding,internationalization,findbugs,Java,Encoding,Internationalization,Findbugs,FindBugs报告了一个bug: 依赖默认编码 找到对方法的调用,该方法将执行字节到字符串(或字符串到字节)转换,并将假定默认平台编码是合适的。这将导致应用程序行为在不同平台之间发生变化。使用替代API并显式指定字符集名称或字符集对象 我像这样使用FileReader(只是一段代码): 到 当我使用PrintWriter时,同样的错误也发生了。现在我有一个问题。当我可以(应该)使用FileReader和PrintWriter时,如果依赖默认编码不是一种好的做法,那我该怎么做呢? 第二个问题是正

FindBugs报告了一个bug:

依赖默认编码 找到对方法的调用,该方法将执行字节到字符串(或字符串到字节)转换,并将假定默认平台编码是合适的。这将导致应用程序行为在不同平台之间发生变化。使用替代API并显式指定字符集名称或字符集对象

我像这样使用FileReader(只是一段代码):

当我使用PrintWriter时,同样的错误也发生了。现在我有一个问题。当我可以(应该)使用FileReader和PrintWriter时,如果依赖默认编码不是一种好的做法,那我该怎么做呢?
第二个问题是正确使用Charset.defaultCharset()?我决定使用这种方法自动定义用户操作系统的字符集

如果文件在应用程序的控制下,并且如果希望以平台的默认编码对文件进行编码,则可以使用默认平台编码。明确地指定它可以让您和未来的维护人员更清楚地知道这是您的意图。例如,对于文本编辑器来说,这是一个合理的默认值,它将编写该平台上任何其他编辑器都可以读取的文件

另一方面,如果要确保文件中可以写入任何可能的字符,则应使用UTF8之类的通用编码

如果文件来自外部应用程序,或者应该与外部应用程序兼容,那么您应该使用该外部应用程序期望的编码


您必须意识到,如果您像在机器上一样编写文件,并像在另一台没有相同默认编码的机器上一样读取文件,那么您就不一定能够读取所编写的内容。使用特定的编码进行写入和读取(如UTF8)可以确保文件始终是相同的,无论写入文件时使用什么平台。

每当读取应用程序之外的文件时,您应该使用默认编码,并且可以假定该文件为用户的本地编码,例如用户编写的文本文件。您可能希望在编写此类文件时使用默认编码,具体取决于用户稍后将如何处理该文件

您不应该对任何其他文件使用默认编码,尤其是与应用程序相关的文件

例如,如果应用程序以文本格式写入配置文件,则应始终指定编码。一般来说,UTF-8始终是一个不错的选择,因为它几乎兼容所有产品。不这样做可能会导致其他国家的用户意外崩溃

这不仅限于字符编码,还包括日期/时间、数字或其他特定于语言的格式。例如,如果您在美国机器上使用默认编码和默认日期/时间字符串,然后尝试在德国服务器上读取该文件,您可能会惊讶于为什么其中一半是乱七八糟的,而另一半是混乱的月/日,或者因为夏令时而关闭一小时。

理想情况下,应该是:

try (InputStream in = new FileInputStream(file);
     Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
     BufferedReader br = new BufferedReader(reader)) {
…或:

try (BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
…假设文件编码为UTF-8


几乎所有不是Unicode转换格式的编码对于自然语言数据来说都是过时的。有些语言如果没有Unicode就无法支持。

当您使用PrintWriter时

File file = new File(file_path);
Writer w = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_16.name());
PrintWriter pw = new PrintWriter(w);
pw.println(content_to_write);
pw.close();

可能值得一提的是,即使使用默认编码,为了清晰起见也会显式指定它。你刚刚做到了:-)我在第一段中添加了一句话。谢谢。好的,但是如果我的应用程序应该与外部应用程序兼容,但我不知道它是编码的,我该怎么办呢。Charset.defaultCharset()方法是否允许确定此编码?请阅读外部应用程序的文档。使用它的GUI并尝试发现它使用的编码。或者用它来写各种字符(ascii、西方、中文等),自己用不同的编码做同样的事情,并比较生成的文件以查看使用了哪种编码。好的文本编辑器可以尝试猜测文件中使用的编码。因此,您也可以尝试使用这样的编辑器打开外部应用程序生成的文件,看看它猜测了什么。
try (InputStream in = new FileInputStream(file);
     Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
     BufferedReader br = new BufferedReader(reader)) {
try (BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
File file = new File(file_path);
Writer w = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_16.name());
PrintWriter pw = new PrintWriter(w);
pw.println(content_to_write);
pw.close();