【问题标题】:Linux copy files from Java programLinux 从 Java 程序复制文件
【发布时间】:2013-03-07 07:30:45
【问题描述】:

我使用 getRuntime() API 编写了一个小的 java 代码,用于将文件从一个目录复制到另一个目录,但它失败了,我不明白为什么?当我从 shell 运行命令时,它运行良好,任何人都可以告诉我我正在做的错误

    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/'

java.lang.UNIXProcess@525483cd

exit: 1

【问题讨论】:

  • 不应该 * 在引号内吗?喜欢:cp -R "/tmp/S1/*" "/tmp/D1/"
  • @Ash:在这种情况下,它不会有任何区别 - 通配符不会在 Runtime.exec() 中扩展。但是,在 shell 提示符下,将 * 放在引号内会防止通过通配符进行扩展——这通常不是人们想要的......
  • 这是我得到的错误 cp: cannot stat `/tmp/S1/*': No such file or directory

标签: java linux copy


【解决方案1】:

它适用于以下代码,

            String[] b = new String[] {"bash", "-c", "cp -R \"" + strSource + "/\"* \"" + strDestination + "/\""};  
        p = Runtime.getRuntime().exec(b);

我google了一下,找到了链接

http://www.coderanch.com/t/423573/java/java/Passing-wilcard-Runtime-exec-command

【讨论】:

    【解决方案2】:

    当您使用Runtime.exec() 的任何变体时,二进制文件会被直接调用,而不是通过shell。这意味着wildcards are not supported,因为没有外壳来扩展它们。

    我建议使用 Java 代码来复制您的文件 - 它会更便携且更安全。除此之外,您可以使用 shell 二进制文件通过其-c 选项执行您的命令。

    【讨论】:

    • 假设我使用 apache commons-io 库中的“FileUtils”类将文件从文件夹 A 复制到 B,它会在操作系统级别传输文件(或)它会使用 JVM 吗?我问,因为我有大小超过 1GB 的文件,如果涉及 JVM 可能是一个问题
    • thkala 是对的。只是扩展他的答案。以 "bash -c cp -R dir1 dir2""sh -c cp ..." 运行您的副本
    • 试过这个 - ` p = Runtime.getRuntime().exec("bash -c cp -R \"" + strSource + "/\"* \"" + strDestination + "/\" ");` 不走运
    • @Sandeep540:你需要在传递给-c时引用整个命令。看看我回答中的链接问题...
    • 知道了,我错了,让我试试
    【解决方案3】:

    除非你真的需要执行系统命令,否则你可以使用标准的 java api 来做到这一点。

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

    【讨论】:

    • 我正在使用 JDK 6,目前无法使用 JDK 7
    • 看看 Apache Commons FileUtils。这也可以使它更容易。 commons.apache.org/proper/commons-io///apidocs/org/apache/…
    • 如果我使用 apache commons-io 库中的“FileUtils”类将文件从文件夹 A 复制到 B,它会在操作系统级别传输文件(或)它会使用 JVM 吗?我在问,因为我有大小超过 1GB 的文件,如果涉及 JVM 可能是个问题
    【解决方案4】:

    下面的代码对我有用。

     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[] 命令并在其中传递命令。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      • 2015-09-26
      相关资源
      最近更新 更多