file.encoding没有任何效果,LC_ALL环境variables做它【JAVA教程】

!
也想出现在这里? 联系我们
信息

file.encoding没有任何效果,LC_ALL环境variables做它,第1张

概述file.encoding没有任何效果,LC_ALL环境variables做它

在使用OpenJDK 1.6.0_22的linux下运行的下列Java程序中,我只需在命令行中列出as参数中的目录内容。 该目录包含具有UTF-8文件名的文件(例如印地语,普通话,德语等)。

import java.io.*; class ListDir { public static voID main(String[] args) throws Exception { //System.setProperty(\”file.enCoding\”,\”en_US.UTF-8\”); System.out.println(System.getProperty(\”file.enCoding\”)); file f = new file(args[0]); for(String c : f.List()) { String absPath = args[0] + \”\” + c; file cf = new file(args[0] + \”/\” + c); System.out.println(cf.getabsolutePath() + \” –> \” + cf.exists()); } } }

如果我将LC_ALLvariables设置为en_US.UTF-8,结果将打印正确。 但是,如果我将LC_ALLvariables设置为POSIX,并从命令行以UTF-8的forms提供file.enCoding和sun.jnu.enCoding属性,则会得到垃圾输出,而cf.exists()将返回false。

你能解释一下这个行为吗? 正如我在这么多网站上看到的,file.enCoding据说足以读取文件名并将其用于 *** 作。 这里看起来这个属性根本没有任何作用。

更新1:如果我将file.enCoding设置为GBK(中文)和LC_ALLvariables为en_US.UTF-8,则cf.exists()返回true。 只有 \’?\’ 出现而不是文件名称。 惊喜o_O。

连字符和撇号字符 – 不同语言的相同ASCII码?

linux上的tchar.h

replace为gettext

locale.setlocale(LC_NUMERIC):如何使它在windows上工作

MFC本地化不适用于windows 7的MUI安装

更新2:更多的调查,它看起来不是Java的问题。 它看起来像linux上的libc使用语言环境设置来翻译文件名编码,这些设置将导致文件找不到错误/exception。 “file.enCoding”是Java如何解释文件名的。

更新3现在看起来问题是Java如何解释文件名。 以下简单的C代码在linux上工作,无论LC_ALL环境variables的文件编码和值如何(我很高兴这certificate了这里给出的答案: https : //unix.stackexchange.com/questions/39175/understanding-unix-file-名称编码 )。 但是我还不清楚Java是如何在LC_ALLvariables上解释的。 现在看OpenJDK的代码。

示例C代码:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> int main(int argc,char *argv[]) { char *argdir = argv[1]; DIR *dp = opendir(argdir); struct dirent *de; while(de = readdir(dp)) { char *abspath = (char *) malloc(strlen(argdir) + 1 + strlen(de->d_name) + 1); strcpy(abspath,argdir); abspath[strlen(argdir)] = \’/\’; strcpy(abspath + strlen(argdir) + 1,de->d_name); printf(\”%d %s \”,de->d_type,abspath); file *fp = fopen(abspath,\”r\”); if (fp) { printf(\”Success\”); } fclose(fp); putchar(\’n\’); } }

如何更改.net Web应用程序中的默认文化设置?

标准函数翻译iso-639代码的语言名称?

如何以独立于区域的方式查找本地组?

gettext-commons找不到资源包

InstallshIEld不显示正确的语言

注意:所以最后我想我已经把它钉死了。 我并不确定这是对的。 但是有了一些代码阅读和测试,这就是我发现的,我没有额外的时间去研究它。 如果有人有兴趣,他们可以检查出来,并告诉这个答案是对的还是错的 – 我会很高兴:)

我使用的参考文献来自OpenJDK网站上的这个tarball: openjdk-6-src-b25-01_may_2012.tar.gz

Java在本地将所有字符串转换为平台的本地编码: jdk/src/share/native/common/jni_util.c – JNU_GetStringPlatformChars() 。 系统属性sun.jnu.enCoding用于确定平台的编码。

sun.jnu.enCoding的值设置为jdk/src/solaris/native/java/lang/java_props_md.c – GetJavaPropertIEs()使用libc的setlocale()方法的jdk/src/solaris/native/java/lang/java_props_md.c – GetJavaPropertIEs() 。 环境变量LC_ALL用于设置sun.jnu.enCoding的值。 在命令提示符处使用-Dsun.jnu.enCoding选项给Java给出的值将被忽略。

调用file.exists()已经被编码在文件jdk/src/share/classes/java/io/file.java ,它返回为

return ((fs.getBooleanAttributes(this) & fileSystem.BA_EXISTS) != 0);

在函数: Java_java_io_UnixfileSystem_getBooleanAttributes0()在jdk/src/share/native/java/io/UnixfileSystem_md.c中本地编码(并跳过通过许多文件进行代码浏览的步骤Java_java_io_UnixfileSystem_getBooleanAttributes0() 。 这里宏WITH_FIELD_PLATFORM_STRING(env,file,IDs.path,path)将路径字符串转换为平台的编码。

所以转换成错误的编码实际上会发送一个错误的C字符串(char数组)到随后调用stat()方法。 它将返回结果该文件无法找到。

LESSON: LC_ALL非常重要

我不知道你在哪里阅读关于file.enCoding 。 我没有看到它与System.getPropertIEs记录的其他标准属性提到。 但从我的实验来看,这个值似乎影响了文件内容的编码,而不是文件名 。 如果file.enCoding是POSIX System.out尤其不会打印非ASCII字符。

另一方面,决定哪个编码适用于文件名的linux方法是当前语言环境设置的LC_CTYPE方面。 我看不出为什么Java应该重写这个。 许多其他平台(特别是windows)总是使用Unicode来表示文件名,而不是字节,因此将文件系统的字节级细节公开给Java应用程序没什么意义。

请参阅java.com上的错误4163515 。 它解释说:

file.enCoding特定于JVM的Sun(现在的Oracle)实现 – 其他人可能不支持它

应被认为是只读的

要更改它,您应该修改JVM运行的环境(这是您使用LC_ALL所做的)

还要注意的是,即使改变你的平台的file.enCoding“起作用”,你也不应该那样做,因为它不会改变Oracle JVM通常使用的默认编码,而只是在一些子系统中。 由于该错误显示了String构造函数使用的字节数组所使用的默认编码不受此设置的影响。

总结

以上是内存溢出为你收集整理的file.encoding没有任何效果,LC_ALL环境variables做它全部内容,希望文章能够帮你解决file.encoding没有任何效果,LC_ALL环境variables做它所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

© 版权声明
THE END
喜欢就支持一下吧
点赞176 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容