2017-03-04 44 views
6

原帖的大多數人都回答如何檢索在Java中運行進程的工作目錄?

下面一個是我已經嘗試與

String workingDirectory = "/home"; 
String command = "cd ../"; 

ProcessBuilder pb = new ProcessBuilder(new String[] { "cmd", "/c", command }); 
pb.directory(new File(workingDirectory)); 
pb.redirectErrorStream(true); 
Process process = pb.start(); 

// Some time later once the process has been closed 
workingDirectory = pb.directory().getAbsolutePath(); 
System.out.println("Path: " + workingDirectory); 

這樣做這是不行的,一旦它完成它出來與代碼同樣的 工作目錄。

任何幫助將不勝感激,這將是一個非常有用的 認爲知道。

更具體地說,我期待在Java中找到 動態創建的進程的工作目錄,例如上面的代碼片段。 這很重要,因爲如上面預定義的命令, 工作目錄有時可能會更改,我想將任何 更改保存到內存中供以後使用。

我找到了一種方法來做到這一點,似乎工作沒有問題

這裏是我正在處理輸入的工作目錄

public int osType = 1; // This is for Windows (0 is for Linux) 

public boolean isValidPath(String path) { 
    try { 
     Paths.get(new File(path).getAbsolutePath()); 
    } catch (InvalidPathException | NullPointerException ex) { 
     return false; 
    } 
    return true; 
} 

public String tracePath(String path) { 
    try { 
     if (!path.contains("%%") && !isValidPath(path)) return null; 
     if (path.contains("%%")) path = path.substring(path.indexOf("%%")); 
     int lastIndex = -1; 
     char filesystemSlash = ' '; 
     if (osType == 0) 
      filesystemSlash = '/'; 
     if (osType == 1) 
      filesystemSlash = '\\'; 
     if (osType == 0) 
      path = path.substring(path.indexOf(filesystemSlash)); 
     if (osType == 1) 
      path = path.substring(path.indexOf(filesystemSlash) - 2); 
     String tmp = path; 
     boolean broken = true; 
     while (!isValidPath(tmp)) { 
      int index = tmp.lastIndexOf(filesystemSlash); 
      if (lastIndex == index) { 
       broken = false; 
       break; 
      } 
      tmp = tmp.substring(0, index); 
      lastIndex = index; 
     } 
     if (broken && lastIndex != -1) { 
      tmp = path.substring(0, lastIndex); 
     } 
     return tmp; 
    } catch (StringIndexOutOfBoundsException ex) { 
     return null; 
    } 
} 

這裏是忽略的方法與路徑問題(不使用它)

public boolean setDirectory(ProcessBuilder pb, String path) { 
    try { 
     pb.directory(new File(new File(path).getAbsolutePath())); 
     return true; 
    } catch (Exception ex) { 
     return false; 
    } 
} 

現在這裏是怎麼了開始爲Windows或Linux的過程

File file = null; 
     if (osType == 1) { 
      ProcessBuilder pb = new ProcessBuilder(new String[] { "cmd", "/c", command + " & echo %% & cd" }); 
      pb.redirectErrorStream(true); 
      if (!workingDirectory.equals("")) 
       setDirectory(pb, workingDirectory); 
      process = pb.start(); 
     } else if (osType == 0) { 
      file = new File("script.sh"); 
      FileWriter writer = new FileWriter(file, false); 
      writer.append(command + " && echo %% && pwd"); 
      writer.flush(); 
      writer.close(); 
      ProcessBuilder pb = new ProcessBuilder(new String[] { "bash", System.getProperty("user.dir") + "/script.sh" }); 
      pb.redirectErrorStream(true); 
      if (!workingDirectory.equals("")) 
       setDirectory(pb, workingDirectory); 
      process = pb.start(); 
     } else 
      return; 

最後這裏是管理過程中的循環和工作目錄

while (process.isAlive() || process.getInputStream().available() > 0) { 
      byte[] returnBytes = new byte[1024]; 
      process.getInputStream().read(returnBytes); 
      char[] arr = new String(returnBytes).trim().toCharArray(); 
      StringBuilder sb = new StringBuilder(); 
      for (int i = 0; i < arr.length; i++) { 
       char c = arr[i]; 
       if (Character.isDefined(c)) 
        sb.append(c); 
      } 
      String response = sb.toString(); 
      if (!response.equals("")) { 
       String path = tracePath(response.trim().replace("\n", "").replace("\r", "")); 
       if (path != null && osType == 1) { 
        if (Paths.get(path).toFile().exists()) 
         workingDirectory = path; 
       } else if (path != null && osType == 0) { 
        if (Paths.get(path).toFile().exists()) 
         workingDirectory = path; 
       } 
       client.sendMessage(response + '\r' + '\n'); 
      } 
     } 
if (file != null) file.delete(); 

下面是從命令接收輸出的網站

Connecting.. 
Connected. 
Success. You have been connected -> Speentie 

bash -c pwd 
/root/hardsceneServer/remoteServer 

%% 
/root/hardsceneServer/remoteServer 

bash -c cd .. 

%% 
/root/hardsceneServer 

bash -c pwd 
/root/hardsceneServer 

%% 
/root/hardsceneServer 

bash -c dir 
ircServer nohup.out remoteServer start.sh start1.sh start2.sh 

%% 
/root/hardsceneServer 

bash -c cd ircServer 

%% 
/root/hardsceneServer/ircServer 

bash -c dir 
HardScene.jar   hardscene_banned.properties start.sh 
hardscene.properties nohup.out 

%% 
/root/hardsceneServer/ircServer 
+0

什麼是命令嗎? –

+0

如果你問如何檢索另一個進程的工作目錄,那麼這是不可能的。 – Andreas

+0

當Linux可以做到這一點時,它是不可能的?我以爲Java也可以與機器接口?必須有一種方法,即使它非常複雜。 – Speentie8081

回答

4

你在找這樣的東西嗎?

System.out.println("Current working directory: " + System.getProperty("user.dir")); 
System.out.println("Changing working directory..."); 
// changing the current working directory 
System.setProperty("user.dir", System.getProperty("user.dir") + "/test/"); 

// print the new working directory path 
System.out.println("Current working directory: " + System.getProperty("user.dir")); 

// create a new file in the current working directory 
File file = new File(System.getProperty("user.dir"), "test.txt"); 

if (file.createNewFile()) { 
    System.out.println("File is created at " + file.getCanonicalPath()); 
} else { 
    System.out.println("File already exists."); 
} 

它輸出:

Current working directory: /Users/Wasi/NetBeansProjects/TestProject 
Changing working directory... 
Current working directory: /Users/Wasi/NetBeansProjects/TestProject/test/ 
File is created at /Users/Wasi/NetBeansProjects/TestProject/test/test.txt 
+0

不是真的,你幾乎可以得到它,當人們在命令窗口中執行某些「cd ../」命令時,會看到它爲那一個命令執行了操作,但它不會將該新目錄保存在Java中的內存中存儲在一個全新的過程中。所以我需要的只是通過某種方式來傳遞進程並獲取該進程的工作目錄,以便稍後可以重用它。 – Speentie8081

+0

@SkorrloreGaming我找到了你。但爲什麼不使用'System.getProperty(「user.dir」)'?你想只保存一個進程的當前工作目錄嗎? –

+0

我想具體的動態過程的工作目錄沒有其他 – Speentie8081

2

我希望找到在Java中動態創建的進程的工作目錄,

你當然可以查找的工作目錄當前Java進程通過查看user.dir系統屬性的值:

String cwd = System.getProperty("user.dir"); 

但找到的工作目錄另一個進程是不可能的,除非您使用特殊的OS調用。在Linux上,如果你知道pid,那麼你可以看看/proc/[pid]/cwd,但在我知道的OSX或Windows中沒有簡單的等價物。

這不起作用,一旦它完成它出來了相同的工作目錄。

是的,你不能發出命令來改變工作目錄,因爲一旦cmd退出,工作目錄將被重置。

this page,您可以通過分配user.dir系統屬性設置工作目錄:

System.setProperty("user.dir", "/tmp"); 

然而,這可能是OS依賴和對我的OSX箱不起作用。例如,下面的代碼創建在同一個目錄中x1x2文件:

new File("x1").createNewFile(); 
// this doesn't seem to do anything 
System.setProperty("user.dir", "/tmp"); 
new File("x2").createNewFile(); 

This answer說有在Java中做到這一點沒有可靠的方法。我一直認爲你不能改變工作目錄,並且你應該使用new File(parent, filename)來顯示文件的存在位置等。

0

你可以做的是使用sysinternals for windows的句柄

https://technet.microsoft.com/en-us/sysinternals/bb896655.aspx

LS -l/PROC/[PID]/FD或PFILES [PID]爲Linux

,發現最後由該方法中使用的文件夾。

String commandToGetOpenFiles="handle... or ls..."; 
BufferedReader reader = new BufferedReader(
     new InputStreamReader(Runtime.getRuntime() 
       .exec(commandToGetOpenFiles).getInputStream())); 

,並開始您處理,並得到PID使用WMIC過程調用創建「CMD」

0

使用此爲您在目前的文件目錄的URL:

URL url = ClassLoader.getSystemResource(FileName); 

它工作在任何地方。不只是你的電腦,即使在雲端。

它返回一個URLjava.net)類型。對於ClassLoader,您不需要導入任何內容。

文件名中,使用您想要獲取路徑的任何文件名。

-1

使用下面的代碼

Path currentRelativePath = Paths.get(""); 
String s = currentRelativePath.toAbsolutePath().toString(); 
System.out.println("Current relative path is: " + s); 
2

它不能在Java中由ProcessBuilderdirectory()方法,因爲它設置了一個進程的工作目錄,而不是其中的二進制是實現的。你必須在另一個層面做到這一點。

如果您使用的是GNU/Linux,whereisupdate-alternative是您最好的選擇。在Windows中,您有where。現在,它涉及到在不同操作系統中使用命令以及解析輸出。這可能很難。

一些僞代碼開始:

  1. 執行whereis加上命令參數,與ProcessBuilder
  2. 嘗試解析輸出。你可能會處理多行輸出。

或者,

  1. 執行update-alternatives加上命令參數,與ProcessBuilder
  2. 嘗試解析輸出。一個命令可能有多種選擇,例如java,您可能安裝了一些不同的JDK。
  3. 或者,列出/var/libs/alternatives中的所有鏈接,並找到你想要的東西,也許用管道。你可以在這裏看到:

https://serverfault.com/questions/484896/is-there-a-way-to-list-all-configurable-alternatives-symlinks-for-similar-com

但是,我還是懷疑你爲什麼這樣做。所以,如果你能澄清原來的要求,這將有很大的幫助。這是爲了避免X-Y problem

+0

+1這對於Linux用戶很有用,但是在測試中這不會按預期工作。我正在尋找該項目的Windows和Linux解決方案,但這不是一個。不過謝天謝地,我在發佈的時候自己找到了一個解決方案。 – Speentie8081

+0

那麼,畢竟你的解決方案是什麼?它令我感興趣。 – FaithReaper

+0

我發佈了我用作編輯問題的最新代碼。 – Speentie8081

0

你的問題不清楚了一點,但如果你想從內部當前進程查找當前目錄,只是做

new File("").getAbsoluteFile().getAbsolutePath(); 
相關問題