0

ビジーボックスを備えたデバイスを実行しています。空白のないフォルダまたはファイルは正しく移動されましたが、空白のあるフォルダは正しく移動されていないようです

public static boolean mv(File source, File target) {
    if (!source.exists() || !target.exists()) {
        return false;
    }
    try {
        StringBuilder command = new StringBuilder("mv -v ");
        command.append('\"');
        command.append(source.getCanonicalPath());
        command.append('\"');
        command.append(' ');
        command.append('\"');
        command.append(target.getCanonicalPath());
        command.append('\"');
        System.out.println(command.toString());
        Process process = Runtime.getRuntime().exec(command.toString());
        StringBuilder output = new StringBuilder();
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = in.readLine()) != null) {
            output.append(line);
        }
        System.out.println(output.toString());
        return process.waitFor() == 0;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

出力は

mv -v "/storage/sdcard0/media/music/Progressive Death Metal" "/storage/sdcard0/Music"

mv 出力はありません。メソッドは "false" (ゼロ以外の終了コード) を返すだけです。

そして、正規パスを使用する必要がありますか、それとも絶対パスを使用してシェルに任せても問題ありませんか?

編集

ファイル名に引用符があると引数が間違っているということも思いついたので、エスケープ文字を追加するメソッドを作成しました

private static String getCommandLineString(String input) {
    return input.replace("\\", "\\\\")
            .replace("\"", "\\\"")
            .replace("\'", "\\\'")
            .replace("`", "\\`")
            .replace(" ", "\\ ");
}

そして今のMVはこんな感じ

public static boolean mv(File source, File target) {
    if (!source.exists() || !target.exists()) {
        return false;
    }
    try {
        StringBuilder command = new StringBuilder("mv -v ");
        command.append(getCommandLineString(source.getAbsolutePath()));
        command.append(' ');
        command.append(getCommandLineString(target.getAbsolutePath()));
        System.out.println(command.toString());
        Process process = Runtime.getRuntime().exec(command.toString());
        StringBuilder output = new StringBuilder();
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = in.readLine()) != null) {
            output.append(line);
        }
        System.out.println(output.toString());
        return process.waitFor() == 0;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

私が得るものは

mv -v /sdcard/media/music/Progressive\ Death\ Metal /sdcard/Music

それでも、ゼロ以外の終了コードがサイレントに表示されます。

4

1 に答える 1

0

ついにそれが機能するようになりました。Execはシェルを要求する必要がありますが、OutputStreamはコマンドを書き込む必要があります。

private static boolean execute(boolean superuser, String command) {
    DataOutputStream os = null;
    try {
        Process process = Runtime.getRuntime().exec(superuser ? "su" : "sh");
        os = new DataOutputStream(process.getOutputStream());
        os.writeBytes(command + "\n");
        os.flush();

        os.writeBytes("exit\n"); 
        os.flush();

        return process.waitFor() == 0;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (os != null) { try { os.close(); } catch (Exception e) {} }
    }
    return false;
}

public static boolean mv(File source, File target) {
    if (!source.exists() || !target.exists()) {
        return false;
    }
    try {
        StringBuilder command = new StringBuilder("mv ");
        command.append(getCommandLineString(source.getAbsolutePath()));
        command.append(' ');
        command.append(getCommandLineString(target.getAbsolutePath()));
        return execute(false, command.toString());
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}
于 2013-02-17T16:47:51.573 に答える