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

使用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 = .

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

谢谢


这与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;
}