Pau*_*lor 2 java linux filesystems
当String转换为unix系统上的实际Path时,我的Java代码出现问题
contains unmappable characters: /out/K/Kyuss/?And the Circus Leaves Town/09 - Size Queen.mp3
java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters: /out/K/Kyuss/?And the Circus Leaves Town/09 - Size Queen.mp3
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.io.File.toPath(File.java:2234)
at com.jthink.songkong.analyse.analyser.SongSaver.saveRenamedFile(SongSaver.java:891)
at com.jthink.songkong.analyse.analyser.SongSaver.realSave(SongSaver.java:809)
at com.jthink.songkong.analyse.analyser.SongSaver.saveSongToFile(SongSaver.java:630)
at com.jthink.songkong.analyse.analyser.SongSaver.saveChanges(SongSaver.java:190)
at com.jthink.songkong.analyse.analyser.SongSaver.call(SongSaver.java:165)
at com.jthink.songkong.analyse.analyser.SongSaver.call(SongSaver.java:59)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)
问题字符是椭圆char'...'(在错误消息输出中显示为?),它不是8位字符,但为什么它需要是我不知道unix系统有这样的限制.
Linux将文件名视为字节字符串.这是应用程序选择解释他们想要的字节字符串.更多信息在这里.通常程序将文件名解释为UTF-8,但这取决于许多因素,包括LANG环境变量.
问题是Java使用LANG变量来猜测文件名使用的编码.如果没有正确设置(例如en_US.UTF-8),它可能会假设您的文件名是ASCII,并且它拒绝编码椭圆char,因为它没有ASCII编码.
重现它的小例子:
import java.io.File;
public class Test {
public static void main(String[] args) {
File f = new File("\u2026");
f.toPath();
}
}
Run Code Online (Sandbox Code Playgroud)
如果你运行它LANG=C就会得到错误.
$ LANG=C java Test
Exception in thread "main" java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters: ?
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.io.File.toPath(File.java:2234)
at Test.main(Test.java:6)
Run Code Online (Sandbox Code Playgroud)
如果你运行LANG=en_US.UTF-8它工作正常.
$ LANG=en_US.UTF-8 java Test
# No crash!
Run Code Online (Sandbox Code Playgroud)
如果你在没有设置的情况下运行它,它将获取LANG你的系统配置的任何东西,如果它不支持unicode,它将抛出.
不幸的是,我认为从您的程序中找不到这种行为的简单方法.UnixPath.encode使用Charset.defaultCharset()并且无法在运行时更改它.您必须确保LANG正确配置.