java.nio.file.InvalidPathException:使用国家字符时格式错误的输入或输入包含不可映射的字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39185613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters when using national characters
提问by Arturas M
I'm trying to create some directories which have national symbols like "??ü" etc. Unfortunately I'm getting this exception whenever that is being attempted:
我正在尝试创建一些具有国家符号(如“??ü”等)的目录。不幸的是,每当尝试这样做时,我都会遇到此异常:
java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters: /home/pi/myFolder/lo?wen
at sun.nio.fs.UnixPath.encode(UnixPath.java:147)
at sun.nio.fs.UnixPath.<init>(UnixPath.java:71)
at sun.nio.fs.UnixFileSystem.getPath(UnixFileSystem.java:281)
at java.nio.file.Paths.get(Paths.java:84)
at org.someone.something.file.PathManager.createPathIfNecessary(PathManager.java:161)
...
at java.lang.Thread.run(Thread.java:744)
My code where it occurs looks like this:
我发生它的代码如下所示:
public static void createPathIfNecessary(String directoryPath) throws IOException {
Path path = Paths.get(directoryPath);
// if directory exists?
if (!Files.exists(path)) {
Files.createDirectories(path);
} else if (!Files.isDirectory(path)) {
throw new IOException("The path " + path + " is not a directory as expected!");
}
}
I searched for possible solutions and most suggest to set the locale to UTF-8, so I thought I would get this fixed if I set the locale in Linux to UTF-8, but I found out that it has already been UTF-8 all the time, and despite newly setting it, I'm still having the same problem.
我搜索了可能的解决方案,大多数建议将语言环境设置为 UTF-8,所以我想如果我将 Linux 中的语言环境设置为 UTF-8,我会解决这个问题,但我发现它已经全部是 UTF-8时间,尽管是新设置的,但我仍然遇到同样的问题。
$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
I'm not having this problem on Windows 7, it creates the directories perfectly, so I'm wondering whether I need to improve the java code to handle this situation better, or to change something in my Linux.
我在 Windows 7 上没有这个问题,它完美地创建了目录,所以我想知道我是否需要改进 java 代码来更好地处理这种情况,或者在我的 Linux 中进行一些更改。
The Linux I'm running it on is a Raspbian on a Raspberry Pi 2:
我运行它的 Linux 是 Raspberry Pi 2 上的 Raspbian:
$ cat /etc/*-release
PRETTY_NAME="Raspbian GNU/Linux 7 (wheezy)"
NAME="Raspbian GNU/Linux"
VERSION_ID="7"
VERSION="7 (wheezy)"
ID=raspbian
ID_LIKE=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
I am running my application on a Tomcat 7 Server (Java version is 1.8 I believe), my setenv.sh starts with: export JAVA_OPTS="-Dfile.encoding=UTF-8 ...
我在 Tomcat 7 服务器上运行我的应用程序(我相信 Java 版本是 1.8),我的 setenv.sh 以: export JAVA_OPTS="-Dfile.encoding=UTF-8 ...
Does anybody have a solution to this problem? I need to be able to use those national symbols in directory/file names...
有没有人有解决这个问题的方法?我需要能够在目录/文件名中使用这些国家符号...
EDIT:
编辑:
After adding the extra option Dsun.jnu.encoding=UTF-8 at the start of my setenv.sh for Tomcat and restarting something changed.
在我的 Tomcat 的 setenv.sh 的开头添加额外选项 Dsun.jnu.encoding=UTF-8 并重新启动更改后的内容后。
Currently the my start of setenv.sh looks like this
目前我的 setenv.sh 开始看起来像这样
export JAVA_OPTS="-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8
it seems like this exception is gone and the folder with the national symbols gets created, however the problem seems to not be solved completely, whenever I try to create/write to files within that directory, I now get:
似乎这个异常消失了,带有国家符号的文件夹被创建,但是问题似乎没有完全解决,每当我尝试创建/写入该目录中的文件时,我现在得到:
java.io.FileNotFoundException: /home/pi/myFolder/lo?wen/Lowen.tmp (No such file or directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:206)
at java.io.FileOutputStream.<init>(FileOutputStream.java:156)
at org.someone.something.MyFileWriter.downloadFiles(MyFileWriter.java:364)
...
at java.lang.Thread.run(Thread.java:744)
The code where it happens looks like this:
它发生的代码如下所示:
// output here
File myOutputFile = new File(filePath);
FileOutputStream out = (new FileOutputStream(myOutputFile));
out.write(bytes);
out.close();
It seems to fail on (new FileOutputStream(myOutputFile)); when it's trying to initialize the FileOutputStream with the File object, which has the path created from a string which was retrieved from the path in the exception above and an added filename at the end.
它似乎失败 (new FileOutputStream(myOutputFile)); 当它尝试使用 File 对象初始化 FileOutputStream 时,该对象具有从字符串创建的路径,该字符串是从上述异常中的路径中检索到的,并在末尾添加了文件名。
So now the directory is created, however writing or creating anything inside it still results in the exception above, although the file inside it doesn't event contain national symbols.
所以现在创建了目录,但是在其中写入或创建任何内容仍然会导致上述异常,尽管其中的文件不包含国家符号。
Creating paths and files in them when they have no national symbols works as perfectly as it did before the change in setenv.sh, so it looks like the problem is connected to the national symbols within the path still...
在没有国家符号的情况下在其中创建路径和文件与更改 setenv.sh 之前一样完美,所以看起来问题仍然与路径中的国家符号有关......
回答by Krzysztof Kaszkowiak
If the national characters are hardcoded in your source, convert the source file to the same encoding. You can use vim:
如果在您的源中硬编码了国家字符,请将源文件转换为相同的编码。你可以使用vim:
vim SourceClassWithHardcodedCharacters.java
:set fileencoding=utf-8<Enter>
:w<Enter>
If there is an issue, you will get a message ("unmappable character (...)").
如果出现问题,您将收到一条消息(“不可映射的字符 (...)”)。
For me, the issue is related either with 1. hardcoding characters in incorrect encoding or 2. losing the encoding somehow during passing the path to the method.
对我来说,这个问题与 1. 编码不正确的硬编码字符或 2. 在将路径传递给方法的过程中以某种方式丢失编码有关。