Pregunta

Actualmente estoy trabajando en una aplicación web que implica montar una unidad y extraer un archivo tar.gz, todo en Java.Dado que la aplicación se ejecuta en un entorno Linux, pensé en intentar usar comandos de Unix como "mount" y "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();

Ejecutar el comando de montaje y el comando de extracción en la terminal funciona bien, pero falla cuando se ejecuta por PRIMERA vez en Java.El segundo proc.waitFor() devuelve el código de salida 2.Sin embargo, ejecutar este código después del primer intento fallido funciona bien.Tengo la sensación de que el problema es que waitFor() no espera hasta que el comando de montaje se complete por completo.¿Me falta algo importante en mi código?

Además, prefiero hacer todo esto en Java, pero me costó mucho descubrir cómo descomprimir un archivo, así que estoy adoptando este enfoque.(Oh, si alguien puede decirme cómo hacer esto, estaría muy feliz).¡Cualquier sugerencia será muy apreciada!

¿Fue útil?

Solución 2

Avanzar. En caso de que alguien se preguntaba, aquí es cómo estoy extraer un archivo tar.gz en Java. Formulado a partir de un par de tutoriales en línea.

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();
}

Otros consejos

Respuesta rápida

Dado que existe una dependencia de comandos externos, simplifíquelo así:

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

Nombralo mount-extract.sh luego llámalo usando un solo Runtime.exec() llamar.

Respuesta semiintegrada

Utilice las API de Java.

Necesitará Runtime.exec para ejecutar el comando de montaje.

Mirando hacia adelante

Dado que Java es una herramienta de desarrollo de software multiplataforma, considere abstraer el comando de montaje en su aplicación para que se derive dinámicamente en función del sistema operativo subyacente.

Ver: ¿Cómo puedo montar una unidad de Windows en Java?

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

Por supuesto, el desarrollo ágil insistiría en que esto no se haga hasta que sea necesario.Así que manténgalo en el fondo de su mente hasta entonces (ya que es posible que nunca ejecute la aplicación en nada que no sean sistemas basados ​​en Unix).

Tome un vistazo a la org.apache.tools.tar paquete en el código base de hormiga. Hay una clase en ese paquete, TarInputStream , que puede ser utilizado para leer archivos tar.

Se puede estar relacionado con la forma en que llama al método.

responder

Básicamente tratar de usar

.exec( String [] command );

en lugar de

.exec( String command );

No estoy seguro de si es incluso relacionado, porque lo mencionas se ejecuta la segunda vez. Darle una oportunidad y háganos saber.

Todo esto se puede hacer en Java, pero hay que ser conscientes de advertencias cuando se trata de procesos nativos.

El comando waitFor () puede no estar haciendo lo que se espera: si el proceso de empezar tiene un proceso hijo que hace el trabajo real que necesita entonces el waitFor (), que devuelve cuando el proceso principal ha terminado, no ha permitido tiempo suficiente para que el proceso hijo para terminar.

Una forma de evitar esto es para recorrer alguna prueba para ver que los procesos nativos pedido hoy han terminado a su satisfacción --- en este caso quizá comprobar si existe alguna java.io.File.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top