2

現在、Runtime.exec で xcopy を使用してファイルをコピーする Java プログラムがあります。しかし、問題は、ファイル名に漢字が含まれている場合、これが機能しないことです。ファイルが見つからないというエラーが発生します。ただし、エクスプローラーからファイル パスをコピーし、コマンド ラインから xcopy を実行すると、コピーが機能します。Windows 7 マシンから実行しています。どんな解決策でも大歓迎です。

ありがとう

これはバグhttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4947220に関連しています。パラメータを引数として渡す代わりに、完全に機能する環境変数を介して渡しました。

4

3 に答える 3

5

なぜ xcopy を使用しているのですか? ジャバを使用。

java.nio.file.Files で試してみてください

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

Files.copy(a,b);

ドキュメントについては、こちらを参照してください。

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...)

于 2011-12-23T22:09:38.740 に答える
2

Java の exec は、文字列をシステム コード ページに変換します。XXI世紀にとっては恥ずべきことですが、それがそうです。

しかし、ここでのボトルネックは Java だけではありません。コンソールにも問題があり、xcopy が独自の共有を持っている可能性があります。

たとえば、cmd.exe を Unicode (/U) として起動したり、コード ページを utf-8 (chcp 65001) に設定したり、コマンドと呼び出しでバッチ ファイルを作成したりするなど、試すことができるブードゥー教がたくさんあります。そのバッチ(したがって、exec関数に高ASCIIはありません)。しかし、私はそれを中継しません。

とにかくすべてが Windows のみなので、おそらく jni を使用して「適切な」exec を実装するか、FileCopy が Java コピーよりも高速かどうかを確認します。

于 2011-12-28T11:29:49.707 に答える
1

大きなファイル、またはファイルとファイルに関連付けられているすべてのシステム権限をコピーする必要がある場合は、java internal File.copy()を使用するとコストがかかりすぎるため、すべての負荷をシステムにオフロードできます。

次のトリックを試してください。まず、exec()の引数としてユーザー文字列配列を使用します。次に、/C引数を指定した「cmd」コマンドの後にパイプで「xcopy」を実行します。isWindows()呼び出しを行う行の近くのサンプルコードを見てください。

秘訣は、xcopyコマンドがCMDシェル内で実行され、/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;
}
于 2011-12-23T22:14:37.563 に答える