简体   繁体   English

用Java挂载和解压缩文件

[英]Mounting and untar'ing a file in Java

I'm currently working on a web application that involves mounting a drive and extracting a tar.gz file, all in Java. 我目前正在开发一个Web应用程序,其中涉及安装驱动器并提取tar.gz文件,所有这些都使用Java。 Since the application runs in a linux environment, I figured I'd try using unix commands like "mount" and "tar". 由于该应用程序在Linux环境中运行,因此我想尝试使用unix命令(例如“ mount”和“ tar”)。

Runtime runtime = Runtime.getRuntime();
Process proc;

String mountCommand = "mount -t cifs -o username=...";
String extractCommand = "tar xzf ..."

proc = runtime.exec(mountCommand);
proc.waitFor();

proc = runtime.exec(extractCommand);
proc.waitFor();

Running the mount command and extract command in the terminal works fine, but fails when FIRST run in java. 在终端中运行mount命令和extract命令可以正常工作,但是在FIRST中以Java运行时失败。 The second proc.waitFor() returns exit code 2. However, running this code after the first failed attempt works fine. 第二个proc.waitFor()返回退出代码2。但是,在第一次失败的尝试之后运行此代码可以正常工作。 I have a feeling that the problem is that waitFor() isn't waiting until the mount command is fully completed. 我感觉到问题是waitFor()直到安装命令完全完成才等到。 Am I missing anything important in my code? 我在代码中缺少任何重要的东西吗?

Also, I'd rather do this all in Java, but I had a really hard time figuring out how to untar a file, so I'm taking this approach. 另外,我宁愿使用Java来完成所有操作,但是我很难弄清楚如何解压缩文件,因此我采用了这种方法。 (oh if anyone can tell me how to do this i would be very happy). (哦,如果有人可以告诉我该怎么做,我会很高兴)。 Any suggestions would be muuuuuuuuuuch appreciated! 任何建议将不胜感激!

Quick Answer 快速回答

Since a dependency on external commands exists, simplify it like this: 由于存在对外部命令的依赖关系,因此请像这样简化它:

#!/bin/bash
mount -t cifs -o username=...
tar xzf ...

Name it mount-extract.sh then call it using a single Runtime.exec() call. 将其命名为mount-extract.sh然后使用单个Runtime.exec()调用进行调用。

Semi-integrated Answer 半综合答案

Use Java APIs. 使用Java API。

You will need Runtime.exec to execute the mount command. 您将需要Runtime.exec来执行安装命令。

Forward Looking 前瞻性

Since Java is a cross-platform software development tool, consider abstracting the mount command in your application to be derived dynamically based on the underlying operating system. 由于Java是跨平台的软件开发工具,因此请考虑将应用程序中的mount命令抽象化,以基于基础操作系统动态派生。

See: How can I mount a windows drive in Java? 请参阅: 如何在Java中挂载Windows驱动器?

See: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#getProperties() 请参阅: http : //java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#getProperties()

Of course, Agile development would insist that this not be done until it is needed. 当然,敏捷开发会坚持认为只有在需要时才这样做。 So keep it in the back of your mind until then (as you might never run the application on anything but Unix-based systems). 因此,在那之前请记住它(因为您可能永远不会在基于Unix的系统上运行该应用程序)。

Making progress. 取得进展。 In case anyone was wondering, here is how I am extracting a tar.gz file in Java. 如果有人想知道,这是我如何在Java中提取tar.gz文件。 Put together from a few online tutorials. 从一些在线教程中汇总。

public static void extract(String tgzFile, String outputDirectory)
    throws Exception {

// Create the Tar input stream.
FileInputStream fin = new FileInputStream(tgzFile);
GZIPInputStream gin = new GZIPInputStream(fin);
TarInputStream tin = new TarInputStream(gin);

// Create the destination directory.
File outputDir = new File(outputDirectory);
outputDir.mkdir();

// Extract files.
TarEntry tarEntry = tin.getNextEntry();
while (tarEntry != null) {
    File destPath = new File(outputDirectory + File.separator + tarEntry.getName());

    if (tarEntry.isDirectory()) {
    destPath.mkdirs();
    } else {
    // If the parent directory of a file doesn't exist, create it.
    if (!destPath.getParentFile().exists())
        destPath.getParentFile().mkdirs();

    FileOutputStream fout = new FileOutputStream(destPath);
    tin.copyEntryContents(fout);
    fout.close();
    // Presserve the last modified date of the tar'd files.
    destPath.setLastModified(tarEntry.getModTime().getTime());
    }
    tarEntry = tin.getNextEntry();
}
tin.close();
}

Take a look at the org.apache.tools.tar package in the Ant codebase. 看一下Ant代码库中的org.apache.tools.tar包。 There is a class in that package, TarInputStream , that can be used to read tar archives. 该软件包中有一个类TarInputStream ,可用于读取tar存档。

It may be related to the way you call the method. 它可能与您调用该方法的方式有关。

See this answer 看到这个答案

Basically try using 基本上尝试使用

.exec( String [] command );

instead of 代替

.exec( String command );

I'm not sure if it is even related, because you mention it runs the second time. 我不确定它是否相关,因为您提到它第二次运行。 Give it a try and let us know. 试试看,让我们知道。

This can all be done in Java, but you have to be aware of caveats when dealing with native processes. 这一切都可以用Java完成,但是在处理本机进程时,您必须注意一些注意事项。

The waitFor() command may not be doing what you hope: if the process you started has a child process that does the actual work you need then the waitFor(), which returns when the parent process has finished, has not allowed enough time for the child process to finish. waitFor()命令可能无法满足您的期望:如果启动的进程有一个子进程来完成您所需的实际工作,则waitFor()(在父进程完成时返回)将没有足够的时间执行子进程完成。

One way to get around this is to loop over some test to see that the native processes you started have finished to your satisfaction---in this case perhaps checking if some java.io.File exists. 解决此问题的一种方法是遍历一些测试,以查看您启动的本机进程是否已满足您的要求-在这种情况下,可能要检查是否存在某些java.io.File。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM