使用java Runtime.exec的Windows xcopy不适用于带有中文字符的文件名
我目前有一个java程序,它使用xcopy和Runtime.exec来复制文件。但现在的问题是,当文件名包含中文字符时,这不起作用。 它给出了一个文件未找到错误。 但是,如果我从资源管理器复制文件路径,并从命令行执行xcopy,则复制可以工作。 我在Windows7机器上执行它。任何解决方案都将不胜感激 谢谢使用java Runtime.exec的Windows xcopy不适用于带有中文字符的文件名,java,unicode,xcopy,Java,Unicode,Xcopy,我目前有一个java程序,它使用xcopy和Runtime.exec来复制文件。但现在的问题是,当文件名包含中文字符时,这不起作用。 它给出了一个文件未找到错误。 但是,如果我从资源管理器复制文件路径,并从命令行执行xcopy,则复制可以工作。 我在Windows7机器上执行它。任何解决方案都将不胜感激 谢谢 这与bug有关。不是将参数作为参数传递,而是通过运行良好的环境变量传递参数。为什么要使用xcopy?使用java 尝试使用java.nio.file.Files来实现 Path a = .
这与bug有关。不是将参数作为参数传递,而是通过运行良好的环境变量传递参数。为什么要使用xcopy?使用java 尝试使用java.nio.file.Files来实现
Path a = ...
Path b = ...
Files.copy(a,b);
请参见此处获取文档:
如果您需要复制大文件,或文件以及与文件相关的所有系统权限,使用java internal file.copy()将过于昂贵,因此您可以将所有负载卸载到系统中 尝试以下技巧-首先,将用户字符串数组作为exec()的参数;其次,在带有/C参数的“cmd”命令之后的管道中执行“xcopy”。请看我调用isWindows()的第行附近的示例代码 诀窍是,您的xcopy命令将在cmdshell中执行,并且/C将在成功执行后终止它。更多关于
Java中的exec将字符串转换为系统代码页。 21世纪是可耻的,但事实就是这样 但Java并不是这里唯一的瓶颈。控制台也有问题,xcopy可能有自己的共享空间 有很多伏都教可以尝试,例如以Unicode(/U)启动cmd.exe,和/或将代码页设置为utf-8(chcp 65001),或者使用命令创建一个批处理文件并调用该批处理(因此exec函数中没有高ascii)。 但我不会重复这一点
因为所有东西都是Windows版的,所以我可能会尝试使用jni实现一个“正确的”exec,或者看看FileCopy是否比Java拷贝快。您是否尝试过ProcessBuilder?它应该比Runime好。exec()也尝试了这一点。但是没有成功…Seego。谢谢你的回复。但当我换成xcopy时,这也不起作用。它给我文件未找到打印出控制台上的copyCommand数组并检查命令是否正确创建这是我的命令看起来像cmd=newstring[]{“cmd”、“/C”、“xcopy”、“/R”、“/C”、“/Y”、“/S”、source.getAbsolutePath()、destPath.getCanonicalPath();我想在Runtime.getRuntime().exec()之前查看该命令。查看要输入到命令中的文件路径很重要,而且getCanonicalPath()可能不是有效的文件系统路径。这是命令看起来像的cmd/C xcopy/R/C/Y/S C:\??.zip C:\test。输出显示找不到???.zip。
public int sysCopyFile(Resource fromResource, Resource toResource) throws ServiceException {
int returnCode = -1;
try {
String[] copyCommand = null;
if ( IOUtils.isWindows() ) {
copyCommand = new String[] {"cmd", "/C", "copy", "/Y", fromResource.getFile().getAbsolutePath(), toResource.getFile().getAbsolutePath()};
} else if ( IOUtils.isUnix() || IOUtils.isMac() ) {
copyCommand = new String[] {"/bin/cp", "-pr", fromResource.getFile().getAbsolutePath(),toResource.getFile().getAbsolutePath()};
}
final Process p = Runtime.getRuntime().exec(copyCommand);
new StreamLogger(p.getErrorStream(), log, StreamLogger.WARN);
new StreamLogger(p.getInputStream(), log, StreamLogger.DEBUG);
returnCode = p.waitFor();
if (returnCode != 0) throw new ServiceException("Unable to to copy. Command: {" + copyCommand[0] + "} has returned non-zero returnCode: " + returnCode);
} catch (IOException e) {
throw new ServiceException(e);
} catch (InterruptedException e) {
throw new ServiceException(e);
}
return returnCode;
}