Монтирование и распаковка файла в Java - PullRequest
1 голос
/ 09 июля 2009

В настоящее время я работаю над веб-приложением, которое включает монтирование диска и извлечение файла tar.gz, все на Java. Поскольку приложение работает в среде 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();

Выполнение команды mount и команды extract в терминале работает нормально, но завершается неудачно, когда FIRST запускается в Java. Второй метод proc.waitFor () возвращает код завершения 2. Однако выполнение этого кода после первой неудачной попытки работает нормально. У меня такое ощущение, что проблема в том, что waitFor () не ждет, пока команда mount полностью не завершится. Я что-то упустил в своем коде?

Кроме того, я бы предпочел сделать все это на Java, но мне было очень трудно понять, как распаковать файл, поэтому я использую этот подход. (о, если кто-нибудь может сказать мне, как это сделать, я был бы очень счастлив). Будем благодарны за любые предложения!

Ответы [ 5 ]

3 голосов
/ 09 июля 2009

Успехов. В случае, если кому-то было интересно, вот как я извлекаю файл tar.gz на Java. Соберите из нескольких онлайн-уроков.

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();
}
3 голосов
/ 09 июля 2009

Быстрый ответ

Поскольку существует зависимость от внешних команд, упростите ее следующим образом:

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

Назовите его mount-extract.sh, затем позвоните, используя один Runtime.exec() вызов.

Полуинтегрированный ответ

Использовать API Java.

Для выполнения команды монтирования вам потребуется Runtime.exec.

Взгляд вперед

Поскольку Java является кроссплатформенным средством разработки программного обеспечения, рассмотрите возможность абстрагирования команды монтирования в вашем приложении для динамического получения на основе базовой операционной системы.

См .: Как я могу смонтировать диск Windows в Java?

См .: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#getProperties()

Конечно, гибкая разработка будет настаивать на том, чтобы этого не делали, пока это не понадобится. Так что держите это в уме до тех пор (вы никогда не сможете запустить приложение ни на чем, кроме Unix-систем).

0 голосов
/ 09 июля 2009

Это может быть связано с тем, как вы вызываете метод.

См. ответ

В основном попробуйте использовать

.exec( String [] command );

вместо

.exec( String command );

Я не уверен, что это вообще связано, потому что вы упоминаете, что он запускается во второй раз. Попробуйте и дайте нам знать.

0 голосов
/ 09 июля 2009

Все это может быть сделано в Java, но вы должны знать о предостережениях при работе с нативными процессами.

Команда waitFor () может не выполнять то, что вы надеетесь: если запущенный вами процесс имеет дочерний процесс, выполняющий всю необходимую вам работу, то waitFor (), которая возвращается после завершения родительского процесса, не разрешается достаточно времени для завершения дочернего процесса.

Один из способов обойти это состоит в том, чтобы пройтись по некоторому тесту, чтобы увидеть, что нативные процессы, которые вы запустили, завершены к вашему удовлетворению - в этом случае, возможно, проверка, существует ли какой-либо файл java.io.File.

0 голосов
/ 09 июля 2009

Посмотрите на пакет org.apache.tools.tar в кодовой базе Ant. В этом пакете есть класс TarInputStream , который можно использовать для чтения архивов tar.

...