2011-08-23 90 views
38

我在写一个简单的命令行Java实用程序。我希望用户能够使用~运算符传入相对于其主目录的文件路径。所以像~/Documents/...如何在文件路径中处理〜

我的问题是有没有办法让Java自动解决这种类型的路径?或者我需要扫描~运算符的文件路径吗?

看来这种类型的功能应该烘焙到File对象中。但它似乎不是。

+1

的OS(S)适合您的效用? –

回答

50

一个简单path = path.replaceFirst("^~",System.getProperty("user.home"));当它从用户得到(制作File之前它)应该足以在大多数情况下工作。

+5

大多数(所有?)shell只会在argumetn *开始时执行替换*'〜'。例如,路径'/ a /〜/ c/d.txt'将被完全解释为由bash写入。 –

+0

@andrzej好然后petr的解决方案更好,但是我的结构更紧凑 –

+14

只要注意,这真的不能一直工作。 “〜otheruser/Documents”也是一个有效的主目录;但是,对于其他用户的“user.home”而言,不是“user.home”。另外,如果代字号是路径的目录部分中的第一个字符,则它只会扩展到主目录。尽管非常规,“a〜”是与主目录无关的有效文件。 –

26

这是特定于shell的扩展,所以你需要在该行的开头来取代它,如果存在的话:

String path = "~/xyz"; 
... 
if (path.startsWith("~" + File.separator)) { 
    path = System.getProperty("user.home") + path.substring(1); 
} 

File f = new File(path); 
... 
+4

不应该是'System.getProperty(“user.home”)+ path.substring(2);' –

+0

是的,谢谢,修正 –

8

正如Edwin Buck在评论中指出的另一个答案,〜otheruser/Documents也应该正确扩展。下面是为我工作的函数:

public String expandPath(String path) { 
    try { 
     String command = "ls -d " + path; 
     Process shellExec = Runtime.getRuntime().exec(
      new String[]{"bash", "-c", command}); 

     BufferedReader reader = new BufferedReader(
      new InputStreamReader(shellExec.getInputStream())); 
     String expandedPath = reader.readLine(); 

     // Only return a new value if expansion worked. 
     // We're reading from stdin. If there was a problem, it was written 
     // to stderr and our result will be null. 
     if (expandedPath != null) { 
      path = expandedPath; 
     } 
    } catch (java.io.IOException ex) { 
     // Just consider it unexpandable and return original path. 
    } 

    return path; 
} 
+1

由于它依赖于ls,因此Dave M提供的expandPath方法仅在路径存在时才有效。 – sfosdal

+1

+1为此启动一个新流程似乎是一个巨大的矫枉过正,但它可能是唯一“正确”的方式。 – minexew

4

与实际路径〜作品人物在其中一个相当精简的回答:

String path = "~/Documents"; 
path.replaceFirst("^~", System.getProperty("user.home")); 
+0

这与@ ratchet的答案有同样的缺陷:'〜foo'将被替换为'/ home/yournamefoo'而不是'/ home/foo'。 – bfontaine