当从Oracle使用Java 7时,File.list()在Mac OS X上检索不正确的NO
当使用Oracle 7中的Java 7时,在Mac OS X上使用File.list()的文件名与NON-ASCII字符不正确地检索有问题。
我使用以下示例: import java.io.*; import java.util.*; public class ListFiles { public static void main(String[] args) { try { File folder = new File("."); String[] listOfFiles = folder.list(); for (int i = 0; i < listOfFiles.length; i++) { System.out.println(listOfFiles[i]); } Map<String,String> env = System.getenv(); for (String envName : env.keySet()) { System.out.format("%s=%s%n",envName,env.get(envName)); } } catch (Exception e) { e.printStackTrace(); } } } 从Apple运行Java 6的这个例子,一切都很好: .... Folder-??ü??ü? 吃饭.txt .... 从Oracle运行Java 7的例子,结果如下: .... Folder-A??O??U??a??o??u???? ??????.txt .... 但是,如果我将环境设置如下(未在上述两种情况下设置): LANG=en_US.UTF-8 来自Oracle的Java 7的结果是如预期的那样: .... Folder-??ü??ü? 吃饭.txt .... 我的问题是我不想设置LANG环境变量。它是一个GUI应用程序,我想要部署为Mac OS X应用程序,并且这样做,LSEnvironment设置 <key>LSEnvironment</key> <dict> <key>LANG</key> <string>en_US.UTF-8</string> </dict> 在Info.plist中没有效果(另见here) 在Mac OS X上的Oracle中,如何在Java 7中正确检索文件名称,而无需设置LANG环境?在Windows和Linux中,此问题不存在。 编辑: 如果我打印个别字节: byte[] x = listOfFiles[i].getBytes(); for (int j = 0; j < x.length; j++) { System.out.format("%02X",x[j]); System.out.print(" "); } System.out.println(); 正确的结果是: Folder-??ü??ü? 46 6F 6C 64 65 72 2D 41 CC 88 4F CC 88 55 CC 88 61 CC 88 6F CC 88 75 CC 88 C3 9F 吃饭.txt E5 90 83 E9 A5 AD 2E 74 78 74 错误的结果是: Folder-A??O??U??a??o??u???? 46 6F 6C 64 65 72 2D 41 EF BF BD EF BF BD 4F EF BF BD EF BF BD 55 EF BF BD EF BF BD 61 EF BF BD EF BF BD 6F EF BF BD EF BF BD 75 EF BF BD EF BF BD EF BF BD EF BF BD ??????.txt EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD 2E 74 78 74 所以可以看到,如果没有设置LANG(仅适用于Java 7的Java 7),那么Files.list()将使用UTF-8“EF BF BD”= Unicode U FFFD =替换字符替换某些字节。 如果其他一切都失败,请为JVM创建一个设置LC_CTYPE环境变量的包装器,然后启动应用程序。 OS X不在乎plist告诉它运行哪个程序?在shell脚本中创建这个包装很简单:#!/bin/bash export LC_CTYPE="UTF-8" # Try other options if this doesn't work exec java your.program.Here 问题在于Java – 来自Apple或Oracle的任何Java版本 – 从文件系统读取文件的名称。文件系统上的文件名称基本上是二进制数据,并且必须对其进行解码,以便在Java中将其用作String。 (你可以在我的博客中加read more about this issue) 编码的检测从平台到版本和版本不同,所以这必须是Apple Java 6和Oracle Java 7不同的地方:Java 6正确地检测到系统设置为UTF-8,而Java 7错误。 奇怪的是,当我尝试使用以下程序重现问题时,我发现Java 6和Java 7正确地使用UTF-8来解码文件名(它们被正确地打印到终端)。对于其他I / O,Java 6u35使用MacRoman作为默认字符集,而Java 7u7使用UTF-8(由file.encoding系统属性显示)。 import java.io.*; public class Test { public static void main(String[] args) { System.setOut(new PrintStream(System.out,true,"UTF-8")); System.out.println(System.getProperty("file.encoding")); for (File f: new File(".").listFiles) { System.out.println(g.getName()); } } } 当我在OS 10.7上运行区域设置时,我得到这个输出。似乎在我的系统上,Java 6不能正确解释为LC_CTYPE给定的值。据我所知,系统没有自定义,一切设置为英文,所以这应该是默认配置: LANG= LC_COLLATE="C" LC_CTYPE="UTF-8" LC_MESSAGES="C" LC_MONETARY="C" LC_NUMERIC="C" LC_TIME="C" LC_ALL= (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |