使用java的Windows xcopy Runtime.exec不适用于带有中文字符的文件名

时间:2011-12-23 21:54:19

标签: java unicode xcopy

我目前有一个java程序,它使用带有Runtime.exec的xcopy来复制文件。但现在的问题是,当文件名有中文字符时,这不起作用。 它给出了一个找不到文件的错误。 但是,如果我从资源管理器复制文件路径并从命令行执行xcopy复制工作。 我正在从Windows 7机器上执行它。任何解决方案都将非常感激。

由于

这与错误http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4947220有关。不是将参数作为参数传递,而是通过完美运行的环境变量传递它们。

3 个答案:

答案 0 :(得分:5)

为什么使用xcopy?使用java。

尝试使用java.nio.file.Files

Path a = ...
Path b = ...

Files.copy(a,b);

请参阅此处了解doc:

http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#copy(java.nio.file.Path,%20java.nio.file.Path,%20java.nio.file.CopyOption...)

答案 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;
}