我想创建一个包含中文字符的文件夹,但文件夹名称错误。中文字符被'?'取代。这是我的代码:
String pathname = "/tmp/测试-" + Bytes.toHexLower(Bytes.random(16));
File file = new File(pathname);
log.info("test", "pathname=[" + pathname + "]");
log.info("test", "path=[" + file.getPath() + "]");
log.info("test", "file.encoding=[" + System.getProperty("file.encoding") + "]");
log.info("test", "defaultCharset=[" + Charset.defaultCharset() + "]");
try {
log.info("test", "canonicalPath=[" + file.getCanonicalPath() + "]");
} catch (IOException e) {
log.error("test", e);
}
file.mkdir();
日志是:
pathname=[/tmp/测试-7ba077d59e8b6b550fe4f032fc30afda]
path=[/tmp/测试-7ba077d59e8b6b550fe4f032fc30afda]
canonicalPath=[/tmp/??-7ba077d59e8b6b550fe4f032fc30afda]
file.encoding=[UTF-8]
defaultCharset=[UTF-8]
文件名“/ tmp /测试-7ba0 ...”更改为“/ tmp / ?? - 7ba0 ...”,但file.encoding和defaultCharset似乎没问题。
是否存在可影响File.getCanonicalPath的其他环境或字符集设置?
UPDATE-1
我添加了以下代码来转储System.getenv():
for (Map.Entry<String, String> entry : new TreeMap<>(System.getenv()).entrySet()) {
log.info("test", "env(" + entry.getKey() + ")=[" + entry.getValue() + "]");
}
在创建错误的文件夹名称的环境中,我得到了:
env(CONSOLETYPE)=[vt]
env(JAVA_OPTS)=[-Dfile.encoding=UTF-8]
env(LANG)=[en_US.UTF-8]
env(LANGSH_SOURCED)=[1]
env(LC_ALL)=[C]
env(NLSPATH)=[/usr/dt/lib/nls/msg/%L/%N.cat]
env(PATH)=[/sbin:/usr/sbin:/bin:/usr/bin]
env(PREVLEVEL)=[N]
env(PWD)=[/root]
env(RUNLEVEL)=[3]
env(SHLVL)=[4]
env(TERM)=[linux]
env(UPSTART_EVENTS)=[runlevel]
env(UPSTART_INSTANCE)=[]
env(UPSTART_JOB)=[rc]
env(XFILESEARCHPATH)=[/usr/dt/app-defaults/%L/Dt]
env(_)=[/usr/bin/java]
env(previous)=[N]
env(runlevel)=[3]
可以使用python脚本启动tomcat(startup.sh)。
在创建正确的文件夹名称的环境中,我得到了:
env(ENV_GROUP)=[FAT]
env(ENV_NAME)=[T6]
env(HISTSIZE)=[1000]
env(HOME)=[/root]
env(HOSTNAME)=[t6.dcfservice.com]
env(LANG)=[en_US.UTF-8]
env(LC_ALL)=[en_US.UTF-8]
env(LOGNAME)=[root]
env(LS_COLORS)=[rs=0:di=01;...
env(MAIL)=[/var/spool/mail/develop]
env(NLSPATH)=[/usr/dt/lib/nls/msg/%L/%N.cat]
env(PATH)=[/sbin:/bin:/usr/sbin:/usr/bin]
env(PWD)=[/home/develop]
env(SHELL)=[/bin/bash]
env(SHLVL)=[2]
env(SUDO_COMMAND)=[/usr/bin/restart_tomcat.sh]
env(SUDO_GID)=[1503]
env(SUDO_UID)=[1503]
env(SUDO_USER)=[develop]
env(TERM)=[vt100]
env(USER)=[root]
env(USERNAME)=[root]
env(XFILESEARCHPATH)=[/usr/dt/app-defaults/%L/Dt]
env(_)=[/usr/bin/java]
使用SSH客户端启动tomcat。
UPDATE-2
根据VGR和zapl的建议使用 Path :
try {
pathname = "/tmp/测试-" + Bytes.toHexLower(Bytes.random(16));
Path path = Paths.get(pathname);
log.info("test", "pathname=[" + pathname + "]");
Files.createDirectory(path);
} catch (Error | RuntimeException | IOException e) {
log.error("test", e);
}
在第一个tomcat(由python脚本启动)中,我得到了:
SEVERE: Exception sending context initialized event to listener instance of class com.iqunxing.cashier.Context
java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters: /tmp/测试-1ca8f20c3deccbf7aabe625397e2d3
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 com.iqunxing.cashier.Context.contextInitialized(Context.java:137)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4994)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1245)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1895)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
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)
在第二个tomcat(由SSH客户端启动)中,我获得了正确的文件夹名称。
UPDATE-3
设置-Dsun.jnu.encoding = UTF-8(当文件夹未正确创建时为ANSI_X3.4-1968)时,File.mkdir()
仍会创建错误的文件夹,但Files.createDirectory(path)
工作正常(显示正确的中文)字符)。
分辨
在zapl提示,在catalina.sh中添加export LC_ALL=en_US.UTF-8
后,File.getCanonicalPath不再返回错误的文件夹名称。