加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

当从Oracle使用Java 7时,File.list()在Mac OS X上检索不正确的NO

发布时间:2020-12-12 13:52:51 所属栏目:百科 来源:网络整理
导读:当使用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 = n
当使用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=

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读