【问题标题】:Runtime.getRuntime.exec() not working for the linux command "tar -xvf filename.tar"Runtime.getRuntime.exec() 不适用于 linux 命令“tar -xvf filename.tar”
【发布时间】:2013-06-27 14:52:49
【问题描述】:

我正在尝试使用 Java 批处理应用程序在 Unix 机器上解压缩文件。

源代码:

String fileName = "x98_dms_12";
       
Runtime.getRuntime().exec("gunzip "+ fileName + ".tar.gz");
System.out.println(" Gunzip:"+"gunzip "+ fileName + ".tar.gz");

Runtime.getRuntime().exec("tar -xvf "+ fileName + ".tar");
System.out.println(" Extract:tar -xvf "+ fileName + ".tar");

问题描述:

当我运行批处理程序时,它不能(完全)工作。只有 gunzip 命令有效,将我的 fileName.tar.gz 转换为 fileName.tar。但是 untar 命令似乎没有做任何事情,而且我的日志或 Unix 控制台中没有错误或异常。

当我在 Unix 提示符下运行相同的命令时,它们运行良好。

注意事项:

  1. 执行路径是正确的,因为它将我的 *.tar.gz 转换为 *.tar
  2. 我无法使用“tar -zxvf fileName.tar.gz”,因为属性“z”在我的系统上不起作用。
  3. 没有抛出错误或异常。

请帮忙。

【问题讨论】:

  • 您确定您的“文件名”变量是“x98_dms_12.tar.gz”吗?因为如果是这样,您最终会得到以下命令 - gunzip x98_dms_12.tar.gz.tar.gz.
  • 打印出这个命令的输出和错误put流
  • 对不起,我的文件名是 x98_dms_12。我在执行 gunzip 语句时连接它。

标签: java unix extract tar


【解决方案1】:

有几点:

  • tar 命令将展开一个相对于您的工作目录的文件,可能需要为您的 Java 进程对象设置该文件
  • 您应该等待解压缩过程完成,然后再启动解压缩过程
  • 您应该处理来自进程的输出流。

这是一个可以扩展/调整的工作示例。它使用一个单独的类来处理流程输出流:

class StreamGobbler implements Runnable {
    private final Process process;

    public StreamGobbler(final Process process) {
        super();
        this.process = process;
    }

    @Override
    public void run() {
        try {
            final BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            reader.close();
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
}

public void extractTarball(final File workingDir, final String archiveName)
        throws Exception {
    final String gzFileName = archiveName + ".tar.gz";
    final String tarFileName = archiveName + ".tar";

    final ProcessBuilder builder = new ProcessBuilder();
    builder.redirectErrorStream(true);
    builder.directory(workingDir);
    builder.command("gunzip", gzFileName);
    final Process unzipProcess = builder.start();

    new Thread(new StreamGobbler(unzipProcess)).start();
    if (unzipProcess.waitFor() == 0) {
        System.out.println("Unzip complete, now untarring");

        builder.command("tar", "xvf", tarFileName);
        final Process untarProcess = builder.start();
        new Thread(new StreamGobbler(untarProcess)).start();
        System.out.println("Finished untar process. Exit status "
                + untarProcess.waitFor());
    }
}

【讨论】:

  • 您建议的代码在 WINDOWS 环境中工作,但是当我在 UNIX 中部署它时它不工作。 java和UNIX服务器之间是否有任何兼容性。相同的 tar 命令在 UNIX 提示符下工作,但不能通过 JAVA 应用程序工作。
  • 适用于 Mac OSX,应该适用于 Unix。它实际上没有任何平台依赖。你得到什么错误?
  • 我试过下面的代码 Process process = Runtime.getRuntime().exec("tar -xvf "+ fileName + ".tar"); BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));字符串错误流=空; int exitValue = process.waitFor(); System.out.println("exitvalue = "+exitValue); while ((errorStream = br.readLine()) != null) { System.out.println("获取响应时出错:"+errorStream);我得到了错误路径或找不到目录。但文件和路径存在。
  • 您是否按照我的示例设置了进程的工作目录?
【解决方案2】:

下面的代码将打印执行命令的输出。检查它是否返回任何错误。

Process p = Runtime.getRuntime().exec("tar -xvf "+ fileName + ".tar");  
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));  
String line = null;  
while ((line = br.readLine()) != null) {  
     System.out.println(line);  
}

【讨论】:

  • 我尝试了你给出的建议。 br.readLine() 本身给出了一个空对象。
  • 我试过下面的代码 Process process = Runtime.getRuntime().exec("tar -xvf "+ fileName + ".tar"); BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));字符串错误流=空; int exitValue = process.waitFor(); System.out.println("exitvalue = "+exitValue); while ((errorStream = br.readLine()) != null) { System.out.println("获取响应时出错:"+errorStream);我得到了错误路径或找不到目录。但文件和路径存在。
  • 嗯...只是为了确认一下,您的 java 应用是否有权访问此文件?
【解决方案3】:

问题是我们给出的命令是 UNIX 命令,所以它不能在 windows 环境下工作。我写了一个脚本文件来解决这个问题,谢谢大家的帮助。 Runtime.getRuntime.exec() 将需要一些时间来执行给定的命令,因此在每个 exec() 之后给 thread.wait(3000) 以完成该过程并转到下一个线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-02
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多