我正在运行一个带有busybox的设备。没有空格的文件夹或文件移动正确,但似乎有空格的文件夹没有正确移动
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"(非零退出代码)。
我必须使用规范路径,还是可以使用绝对路径并将其留给shell?
编辑
我还发现,如果文件名有引号,那么参数将是错误的,所以我制定了一个添加转义字符的方法
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
但我仍然得到无声的非零退出代码。
终于开始工作了。Exec应该请求shell,而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("exitn");
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;
}
}