我目前有一个java程序,它使用带有Runtime.exec的xcopy来复制文件。但现在的问题是,当文件名有中文字符时,这不起作用。 它给出了一个找不到文件的错误。 但是,如果我从资源管理器复制文件路径并从命令行执行xcopy复制工作。 我正在从Windows 7机器上执行它。任何解决方案都将非常感激。
由于
这与错误http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4947220有关。不是将参数作为参数传递,而是通过完美运行的环境变量传递它们。
答案 0 :(得分:5)
为什么使用xcopy?使用java。
尝试使用java.nio.file.Files
Path a = ...
Path b = ...
Files.copy(a,b);
请参阅此处了解doc:
答案 1 :(得分:2)
Java中的exec将字符串转换为系统代码页。 对于二十一世纪而言,这是可耻的,但事实就是如此。
但Java不是这里唯一的瓶颈。控制台也存在问题,xcopy可能拥有自己的共享。
您可以尝试很多伏都教,例如将cmd.exe作为Unicode(/ U)启动,和/或将代码页设置为utf-8(chcp 65001),或者创建一个批处理文件命令并调用该批处理(因此在exec函数中没有高位ascii)。 但我不会转发那个。
因为无论如何一切都只是Windows,我可能会尝试使用jni来实现“正确”的exec,或者看看FileCopy是否比Java副本更快。
答案 2 :(得分:1)
如果您需要复制大文件或文件以及与文件关联的所有系统权限,使用java内部File.copy()将会过于昂贵,因此您可以将所有负载卸载到系统中。
尝试以下技巧 - 首先,用户字符串数组作为exec()的参数;第二,在带有/ C参数的'cmd'命令后,在管道中执行'xcopy'。查看我在isWindows()调用的行附近的示例代码。
诀窍是你的xcopy命令将在CMD shell中执行,而/ C将在成功执行后终止它。有关CMD.exe的更多信息。
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;
}