清除给定的命令行字符串以匹配文件路径

时间:2010-08-24 10:05:55

标签: java windows string command-line-arguments

我的应用程序使用命令行处理字符串。我需要将字符串转换为给定的可执行文件,例如:
"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
还有其他有用的想法吗?

4 个答案:

答案 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)

向后索引可以防止您在以下情况下过早发现现有文件:

  • C:\我
  • C:\ My File

您可以在测试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;
    }

}