Windows xcopy using java Runtime.exec not working for filenames with chinese characters

不羁岁月 提交于 2019-12-11 02:59:40

问题


I currently have a java program that uses xcopy with Runtime.exec to copy files. But the problem now is that when the file name has chinese characters this does not work. It gives a file not found error. However if i copy the file path from explorer and do xcopy from the command line copy works. I am executing it from a Windows 7 machine. Any solutions will be much appreciated.

Thanks

This is related to the bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4947220. Instead of passing the parameters as arguments, passed them via environment variables which worked perfectly.


回答1:


Why are you using xcopy? Use java.

Try to do it with java.nio.file.Files

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

Files.copy(a,b);

See here for 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...)




回答2:


The exec in Java converts the strings to the system code page. Shameful, for the XXI century, but that's how it is.

But Java is not the only bottleneck here. The console is also problematic, and xcopy might have it's own share.

There is a lot of voodoo that you can try, for instance starting cmd.exe as Unicode (/U), and/or setting the code page to utf-8 (chcp 65001), or create a batch file with the command and call that batch (so no high-ascii in the exec function). But I would not relay on that.

Since everything is Windows only anyway, I would probably try using jni to implement a "proper" exec, or see if FileCopy is faster than the Java copy.




回答3:


If you need to copy large files, or files and all the system permissions associated with a file, using java internal File.copy() will be too expensive, so you can offload all the load to your system.

Try the following trick - first, user string array as an argument to exec(); second, execute your 'xcopy' in a pipe after 'cmd' command with /C argument. Look at the sample code near line where I make isWindows() call.

The trick is that your xcopy command will be executed inside CMD shell, and /C will terminate it after successful execution. More aboutCMD.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;
}


来源:https://stackoverflow.com/questions/8620952/windows-xcopy-using-java-runtime-exec-not-working-for-filenames-with-chinese-cha

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!