我的应用程序使用命令行处理字符串。我需要将字符串转换为给定的可执行文件,例如:
"C:\windows\system32\notepad.exe bla.txt" => C:\windows\system32\notepad.exe
"C:\windows\system32\ipconfig /all" => C:\windows\system32\ipconfig
"D:\this is my path\thisismyexe.exe -l this -p are -m my -l parameters" => D:\this is my path\thisismyexe.exe
我目前的想法更像是一种解决方法:
String path = cmdLineString;
while (!new File(path).exists() && path.lastIndexOf(" ") != -1) {
path = path.substring(0, path.lastIndexOf(" "));
}
if (new File(path).exists())
//go on
还有其他有用的想法吗?
答案 0 :(得分:1)
我认为最好的方法是解析字符串,包括正确的引号处理和切断第一个空格(或任何规范说明)。
正如BigMac66已经提到的那样,让行为正确并不容易。
但它比使用FileIO.Exists(str)
进行猜测更清晰,应该更安全(正确实施时)并且可能更快,因为它不需要IO。
概念代码的一个小证明非常容易和简短,并处理这样的情况:
"C:\Users\xod\my file.exe" /run "asdf 123" -> "C:\Users\xod\my file.exe"
C:\Users\xod\test.exe asdf -> "C:\Users\xod\test.exe"
代码:
public String GetExecutable(String cmdline) {
var executable = new StringBuilder();
var inquote = false;
foreach (var c in cmdline.ToCharArray()) {
if (c == '\"')
inquote = !inquote;
else if (!inquote && c == ' ')
break;
else
executable.Append(c);
}
return executable.ToString();
}
答案 1 :(得分:0)
如果路径不包含空格(并且您的示例没有),答案很简单:
String strippedPath = unstrippedPath.replaceFirst(" .*","");
//strippes everything after the first space
但是:对于C:\ documents和settings \ yourname \ etc
等路径,这将失败答案 2 :(得分:0)
通过查看和合并文件系统规则,您可以尝试改进解析;例如,尝试here。
答案 3 :(得分:0)
向后索引可以防止您在以下情况下过早发现现有文件:
您可以在测试File.exists时添加可执行文件后缀,以便从ipconfig中捕获ipconfig.exe。
您可能不希望这样做,但您最终可以尝试执行生成的字符串来测试它是否是可执行文件。这对任意输入来说都是一件危险的事情。
public class Example
{
public static void main(String[] args)
{
String[] samples = {
"C:\\windows\\system32\\notepad.exe bla.txt",
"C:\\WINDOWS\\system32\\ipconfig /all",
System.getProperty("user.home") + " foo bar"
};
for (String s: samples) {
File f = getFile(s, new String[]{"exe", "cmd"});
System.out.println(f);
// you probably don't want to do this
Process p = null;
try {
p = Runtime.getRuntime().exec(f.toString());
} catch (IOException e) {
System.err.println("Not executable: " + f);
} finally {
if (p != null) {
p.destroy();
}
}
}
}
public static File getFile(String cmd, String[] suffixes)
{
StringBuilder buffer = new StringBuilder(cmd);
while(true) {
File f = new File(buffer.toString());
if (f.exists()) {
return f;
} else {
for (String suffix: suffixes) {
f = new File(f.toString() + "." + suffix);
if (f.exists()) {
return f;
}
}
}
int start = buffer.lastIndexOf(" ");
if (start <= 0) {
break;
}
buffer.delete(start, buffer.length());
}
return null;
}
}