2009-07-08 6 views
1

Je travaille actuellement sur une application web qui consiste à monter un lecteur et à extraire un fichier tar.gz, le tout en Java. Puisque l'application s'exécute dans un environnement Linux, j'ai pensé que j'essaierais d'utiliser des commandes unix comme "mount" et "tar". L'exécution de la commande mount et de la commande extract dans le terminal fonctionne correctement, mais échoue lors de l'exécution FIRST en Java. Le second proc.waitFor() renvoie le code de sortie 2. Cependant, l'exécution de ce code après la première tentative échouée fonctionne correctement. J'ai le sentiment que le problème est que waitFor() n'attend pas que la commande mount soit complètement terminée. Est-ce que je manque quelque chose d'important dans mon code?Montage et démontage d'un fichier en Java

En outre, je préfère faire tout cela en Java, mais j'ai eu beaucoup de mal à comprendre comment décompresser un fichier, donc je prends cette approche. (oh si quelqu'un peut me dire comment faire cela, je serais très heureux). Toutes les suggestions seraient muuuuuuuuuuch apprécié!

Répondre

2

Progresser. Au cas où quelqu'un se poserait la question, voici comment j'extrais un fichier tar.gz en Java. Mettre en place à partir de quelques tutoriels en ligne.

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

Jetez un coup d'œil au paquet org.apache.tools.tar dans la base de code Ant. Il y a une classe dans ce paquet, TarInputStream, qui peut être utilisée pour lire les archives tar.

+0

Oui, cela semble être le chemin à suivre, mais je ne pouvais pas comprendre comment conserver les dernières dates modifiées sur les fichiers extraits lors de l'utilisation. – Matthew

0

Cela peut être lié à la façon dont vous appelez la méthode.

Voir cette answer

essayer Fondamentalement utilisant

.exec(String [] command); 

au lieu de

.exec(String command); 

Je ne sais pas si elle est encore liée, parce que vous le dites court la deuxième fois. Essayez-le et faites-le nous savoir.

+0

Merci pour l'entrée, mais cela ne semble pas fonctionner. D'après ce que j'ai lu, cela appelle simplement un exec après l'autre sans attendre que chaque processus se termine. – Matthew

+0

: (Trop triste.) Eh bien, ce n'est pas vraiment une séparation précise des arguments, donc l'option "option de paramètre de commande" est transformée en 4 parties (commande, paramètre, option, option) et c'est tout. dans le mauvais ordre et il envoie "commande paramètre" "option option" en utilisant deux chaînes au lieu de 4. – OscarRyz

0

Tout cela peut être fait en Java, mais vous devez être conscient des mises en garde lorsqu'il s'agit de processus natifs. La commande waitFor() ne fait peut-être pas ce que vous espérez: si le processus que vous avez démarré a un processus fils qui effectue le travail dont vous avez besoin, waitFor(), qui retourne lorsque le processus parent est terminé, n'a pas laissé suffisamment de temps pour que le processus de l'enfant se termine. Une façon de contourner ce problème est de faire une boucle sur un test pour voir si les processus natifs que vous avez démarrés sont terminés à votre satisfaction. Dans ce cas, vérifiez peut-être s'il existe un fichier java.io.File.

+0

Ah, cela a du sens.Utiliser ce truc de fichier fonctionnerait, mais il se sent tellement hackish ... Je pense que je vais regarder – Matthew

3

réponse rapide

Depuis une dépendance sur les commandes externes existe, simplifier comme ceci:

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

Nom il mount-extract.sh ensuite appeler à l'aide d'un seul appel Runtime.exec().

Réponse

Utiliser les API Java semi-intégré.

Vous aurez besoin Runtime.exec pour exécuter la commande de montage.

Forward Looking

Depuis Java est un outil de développement logiciel multi-plateforme, pensez à abstraire la commande de montage dans votre application pour dériver dynamiquement en fonction du système d'exploitation sous-jacent.

Voir: How can I mount a windows drive in Java?

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

Bien sûr, le développement Agile insistait pour que ce ne soit pas fait jusqu'à ce qu'il soit nécessaire. Alors gardez-le dans le dos de votre esprit jusque-là (comme vous ne pourriez jamais exécuter l'application sur autre chose que les systèmes basés sur Unix).

+0

Très utile, merci beaucoup J'ai juste essayé la première méthode rapide, mais elle a échoué à cause du même problème Le script bash n'a pas attendu la fin du montage avant l'exécution de la commande tar et le programme a explosé Je vais essayer une seconde fois d'extraire avec Java J'ai effectivement essayé d'utiliser une bibliothèque tar plus tôt, mais je n'ai pas pu déterminer comment conserver les dernières dates modifiées dans les fichiers extraits s o J'ai abandonné. Il doit y avoir un moyen facile de faire cela. Il y a aussi une bibliothèque SMB (jcifs.samba.org) qui semble très prometteuse. – Matthew

+0

Maintenant, vous savez quelque chose que vous n'avez pas fait auparavant: la commande mount se termine avant qu'elle ne se termine. Une autre solution consiste à utiliser sleep et loop jusqu'à ce que le fichier puisse être lu (ou qu'un nombre fixe d'itérations soit passé). –