Java 从字符串创建路径时出错,linux 是否将文件名限制为 8 位字符集
Java error creating Path from String, does linux limit filenames to 8bit charset
我的 Java 代码在 Unix 系统上将字符串转换为实际路径时出现问题
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)
问题字符是椭圆字符“...”(在错误消息输出中显示为?),它不是 8 位字符,但为什么需要它我不知道 unix 上有这样的限制系统。
Linux 将文件名视为字节串。是应用程序选择以他们想要的方式解释字节串。 More info here. 通常程序将文件名解释为 UTF-8,但这取决于许多因素,包括 LANG
环境变量。
问题是 Java 使用 LANG
变量来猜测您的文件名使用的编码。如果您没有正确设置它(例如 en_US.UTF-8
),它可能会假定您的文件名是 ASCII,并且它拒绝对椭圆字符进行编码,因为它没有 ASCII 编码。
重现它的小例子:
import java.io.File;
public class Test {
public static void main(String[] args) {
File f = new File("\u2026");
f.toPath();
}
}
如果你 运行 它与 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)
如果你 运行 它与 LANG=en_US.UTF-8
它工作正常。
$ LANG=en_US.UTF-8 java Test
# No crash!
如果你 运行 它没有设置 LANG
它会选择你的系统配置的任何东西,如果它不支持 unicode 就会抛出。
不幸的是,我看不到从您的程序中修复此行为的简单方法。 UnixPath.encode
使用 Charset.defaultCharset()
和 there's no way to change it at runtime。您必须确保 LANG
配置正确。
我的 Java 代码在 Unix 系统上将字符串转换为实际路径时出现问题
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)
问题字符是椭圆字符“...”(在错误消息输出中显示为?),它不是 8 位字符,但为什么需要它我不知道 unix 上有这样的限制系统。
Linux 将文件名视为字节串。是应用程序选择以他们想要的方式解释字节串。 More info here. 通常程序将文件名解释为 UTF-8,但这取决于许多因素,包括 LANG
环境变量。
问题是 Java 使用 LANG
变量来猜测您的文件名使用的编码。如果您没有正确设置它(例如 en_US.UTF-8
),它可能会假定您的文件名是 ASCII,并且它拒绝对椭圆字符进行编码,因为它没有 ASCII 编码。
重现它的小例子:
import java.io.File;
public class Test {
public static void main(String[] args) {
File f = new File("\u2026");
f.toPath();
}
}
如果你 运行 它与 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)
如果你 运行 它与 LANG=en_US.UTF-8
它工作正常。
$ LANG=en_US.UTF-8 java Test
# No crash!
如果你 运行 它没有设置 LANG
它会选择你的系统配置的任何东西,如果它不支持 unicode 就会抛出。
不幸的是,我看不到从您的程序中修复此行为的简单方法。 UnixPath.encode
使用 Charset.defaultCharset()
和 there's no way to change it at runtime。您必须确保 LANG
配置正确。