2013-03-07 64 views
4

我已經用getRuntime()API編寫了一個小型java代碼來將文件從一個目錄複製到另一個目錄,但它失敗了,我無法理解爲什麼?當我從shell中運行命令它運行良好,任何人都可以,請讓我知道我現在做的錯誤從Java程序Linux複製文件

private static void copyFilesLinux(String strSource, String strDestination) { 

    String s; 
    Process p; 
    try { 
     // cp -R "/tmp/S1/"* "/tmp/D1/" 
     p = Runtime.getRuntime().exec(
       "cp -R '" + strSource + "/'* '" + strDestination + "/'"); 
     System.out.println("cp -R \"" + strSource + "/\"* \"" + strDestination + "/\""); 
     System.out.println("cp -R '" + strSource + "/'* '" + strDestination + "/'"); 
     System.out.println(p.toString()); 
     BufferedReader br = new BufferedReader(new InputStreamReader(
       p.getInputStream())); 
     while ((s = br.readLine()) != null) 
      System.out.println("line: " + s); 
     p.waitFor(); 
     System.out.println("exit: " + p.exitValue()); 
     p.destroy(); 
    } 
    catch (InterruptedException iex) { 
     iex.printStackTrace(); 
    } 
    catch (IOException iox) { 
     iox.printStackTrace(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

輸出:

cp -R "/tmp/S1/"* "/tmp/D1/" 

cp -R '/tmp/S1/'* '/tmp/D1/' 

[email protected] 

exit: 1 
+0

不應該在引號內?像:'cp -R「/ tmp/S1/*」「/ tmp/D1 /」' – Ash 2013-03-07 07:45:48

+1

@Ash:在這種情況下,它沒有區別 - 通配符不會在Runtime.exec()中擴展。然而,在shell提示符下,將'*'放在引號內可以防止通過globbing擴展 - 這通常不是人們想要的... – thkala 2013-03-07 07:58:37

+0

這是我得到的錯誤cp:can stat'/ tmp/S1/* ':沒有這樣的文件或目錄 – Sandeep540 2013-03-07 07:59:24

回答

1

你可以做,使用標準的Java API,除非你有真的需要執行系統命令。

http://docs.oracle.com/javase/tutorial/essential/io/copy.html

+0

我正在使用JDK 6,截至目前無法使用JDK 7 – Sandeep540 2013-03-07 08:00:21

+0

查看Apache Commons FileUtils。這也可以使它更容易。 http://commons.apache.org/proper/commons-io///apidocs/org/apache/commons/io/FileUtils.html – 2013-03-07 08:03:38

+0

如果我使用apache commons-io庫中的「FileUtils」類來複制文件從文件夾A到B,它是否會在操作系統級別傳輸文件(或)它會使用JVM嗎?我問,因爲我有超過1GB大小的文件,並且如果涉及JVM,可能會出現問題 – Sandeep540 2013-03-07 08:06:07

2

當您使用的Runtime.exec()任何變化,二元被稱爲直接,而不是通過一個殼。這意味着wildcards are not supported,因爲沒有外殼可以擴展它們。

我會建議使用Java代碼來複制文件 - 它會更便攜,更安全。除此之外,你可以使用shell二進制來通過其-c選項執行你的命令。

+0

假設我使用apache commons-io庫中的「FileUtils」類將文件夾A中的文件複製到B,它會不會在操作系統級別(或)傳輸文件是否會使用JVM? 我在問,因爲我的文件大小超過1GB,如果涉及到JVM,它可能是一個問題 – Sandeep540 2013-03-07 08:01:34

+0

_thkala_是對的。只是擴大他的答案。運行你的副本爲_「bash -c cp -R dir1 dir2」_或_「sh -c cp ...」_ – 2013-03-07 08:10:24

+0

試過這個 - 「p = Runtime.getRuntime().exec(」bash -c cp -R \「」+ strSource +「/ \」* \「」+ strDestination +「/ \」「);'不幸運 – Sandeep540 2013-03-07 08:22:21

1

它爲我用下面的代碼。

public static void main(String []args) throws Exception{ 
     String s; 
     Process p; 
     try { 
      String b[] = new String[4]; 
      b[0] = "cp"; 
      b[1] = "-R"; 
      b[2] = "HelloWorld.java"; 
      b[3] = "abc.java"; 

      p = Runtime.getRuntime().exec(b); 
      BufferedReader br = new BufferedReader(
       new InputStreamReader(p.getInputStream())); 
      while ((s = br.readLine()) != null) 
       System.out.println("line: " + s); 
      p.waitFor(); 
      System.out.println ("exit: " + p.exitValue()); 
      p.destroy(); 
     } catch (Exception e) {}   
    } 
} 

創建命令的String[]並傳入的命令。