file.encoding无效,LC_ALL环境变量会起作用

如何解决file.encoding无效,LC_ALL环境变量会起作用

注意:所以最后我认为我已经确定了。 我不确定这是正确的。但是通过一些代码阅读和测试,这就是我发现的内容,而且我没有更多时间研究它。如果有人有兴趣,他们可以检查一下,并确定这个答案是对还是错- 我会很高兴:)

我使用的参考资料来自OpenJDK的站点上的以下压缩包:

  1. Java通过以下方法将所有字符串本地转换为平台的本地编码jdk/src/share/native/common/jni_util.c - JNU_GetStringPlatformChars()。系统属性sun.jnu.encoding用于确定平台的编码。

  2. 的值sun.jnu.encodingjdk/src/solaris/native/java/lang/java_props_md.c - GetJavaProperties()使用setlocale()libc的方法设置的。环境变量LC_ALL用于设置的值sun.jnu.encoding。在命令提示符下使用-Dsun.jnu.encodingJava选项使用Java 给出的值将被忽略。

  3. 呼叫File.exists()已被编码在文件中jdk/src/share/classes/java/io/File.java,并且返回为

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

  1. getBooleanAttributes()jdk/src/share/native/java/io/UnixFileSystem_md.c在函数中的 本地编码(并且我跳过了浏览许多文件的代码的步骤)Java_java_io_UnixFileSystem_getBooleanAttributes0()。此处,宏 WITH_FIELD_PLATFORM_STRING(env, file, ids.path, path)将路径字符串转换为平台的编码。

  2. 因此,转换为错误的编码实际上会将错误的C字符串(char数组)发送给随后的stat()方法调用。它将返回结果,找不到文件。

LC_ALL非常重要

解决方法

在下面的使用OpenJDK
1.6.0_22在Linux中运行的Java程序中,我仅在命令行中列出了作为参数接收的目录的内容。该目录包含文件名称为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_ALL变量设置为en_US.UTF-8,则结果打印良好。但是,如果我将LC_ALL变量设置为POSIX并从命令行以UTF-8形式提供file.encoding和sun.jnu.encoding属性,则会得到垃圾输出,并且cf.exists()返回false。

能否请您解释这种行为。当我在许多网站上阅读时,据说file.encoding足以读取文件名并将其用于操作。在这里,该属性似乎完全无效。

更新1:
如果将file.encoding设置为GBK(中文),将LC_ALL变量设置为en_US.UTF-8,则cf.exists()返回true。只有 ‘?’
出现而不是文件名。给o_O惊喜。

更新2:进行
更多调查,这似乎不是Java问题。看起来Linux上的libc使用语言环境设置来转换文件名编码,而这些设置将导致找不到文件错误/异常。“
file.encoding”用于Java解释文件名的方式。

更新3
现在看起来的问题是Java如何解释文件名。不管文件编码和LC_ALL环境变量的值如何,以下简单的C代码都可以在Linux上运行(我很高兴这证明了此处给出的答案:https :
//unix.stackexchange.com/questions/39175/understanding-unix-file-
名称编码)。但是我仍然不清楚Java如何解释LC_ALL变量。现在研究一下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');
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?