2010-11-15 4 views
1

Dans une application web java 6, j'essaie de récupérer une grande quantité de sortie à partir d'une commande exécutée. J'ai "emprunté/volé/basé" sur le javaworld article. Le problème auquel je suis confronté est que la longueur semble dépasser une limite de taille puisque la sortie est coupée. J'ai sorti les données dans un fichier afin que je puisse voir la taille de ce qui est retourné, et c'est exactement 32K (32768). J'ai expérimenté avec la modification de la taille par défaut du tampon (voir Constructeur BufferedReader), mais je n'ai observé aucune modification de la longueur des données retournées, quelle que soit la valeur de la taille mise en mémoire tampon (très petite à très grande) .Limite de taille sur BufferedReader dépassée?

Un conseil serait grandement apprécié!

public class StreamGobbler extends Thread { 

private InputStream is; 
private String type; 
private List<String> output; 

public StreamGobbler(InputStream is, String type) { 
    this.is = is; 
    this.type = type; 
} 

@Override 
public void run() { 
    try { 
     InputStreamReader isr = new InputStreamReader(is); 
     BufferedReader br = new BufferedReader(isr); 
     String line = null; 
     this.output = new ArrayList<String>(); 
     while ((line = br.readLine()) != null) { 
      this.getOutput().add(line + "\n"); 
      System.out.println(type + ">" + line); 
     } 
     br.close(); 
    } catch (IOException ioe) { 
     System.err.println("ERROR: " + ioe.getMessage()); 
    } 
} 

/** 
* @return the output 
*/ 
public List<String> getOutput() { 
    return output; 
} 

}

public class JobClassAds { 

private String CONDOR_HISTORY = "condor_history"; 
private String CONDOR_HISTORY_XML = CONDOR_HISTORY + " -xml"; 
private String CONDOR_HISTORY_LONG = CONDOR_HISTORY + " -long"; 

public String getHistory() { 
    try { 
     Runtime runtime = Runtime.getRuntime(); 
     String exec = CONDOR_HISTORY_LONG; 
     Process process = runtime.exec(exec); 
     System.out.println("Running " + exec + " ..."); 

     // Error message 
     StreamGobbler errGobbler = new StreamGobbler(process.getErrorStream(), "ERROR"); 

     // Output 
     StreamGobbler outGobbler = new StreamGobbler(process.getInputStream(), "OUTPUT"); 

     Thread outThread = new Thread(outGobbler); 
     Thread errThread = new Thread(errGobbler); 

     outThread.start(); 
     errThread.start(); 

     outThread.join(); 
     errThread.join(); 

     /* 
     String line = null; 

     while ((line = input.readLine()) != null) { 
      System.out.println(line); 
      content.append(line); 
     } 

     * 
     */ 

     int exitVal = process.waitFor(); 

     List<String> output = outGobbler.getOutput(); 
     String inputString = ""; 
     for (String o : output) { 
      inputString += o; 
     } 

     System.out.println(exec + " Exited with error code " + exitVal); 

     BufferedWriter out = new BufferedWriter(new FileWriter("/tmp/history_result.xml")); 
     out.write(inputString); 
     out.close(); 
     return inputString; 

    } catch (Exception e) { 
     System.err.println(e.getMessage()); 
     return null; 
    } 
} 
+0

La modification de la taille de la mémoire tampon sur BufferedReader ne modifie que la quantité de mémoire temporaire utilisée en interne. BufferedReader n'a pas de limite de taille, vous devriez donc pouvoir lire toute la sortie avec ce code. Avez-vous vérifié que condor_history -long produit lui-même la sortie complète et ne s'arrête pas à 32k? – Zarkonnen

+0

Merci d'avoir clarifié. L'exécution de la commande renvoie la sortie complète. – samiam

Répondre

0

Le problème est pas avec la taille du tampon de BufferedReader.

Je pense que la cause réelle est quelque chose que fait la commande externe. Je soupçonne qu'il est en train de renflouer sans rincer son flux stdout. Notez que vous "glissez" mais ne publiez pas le flux stderr de la commande. C'est là que vous pouvez trouver la preuve indiquant la véritable cause du problème.


Par ailleurs, vous utilisez la classe StreamGobbler de façon suboptimale. Il étend Thread donc de la manière prévue à utiliser est:

SteamGobbler sg = new StreamGobbler(...); 
    sg.start(); 
    sg.join(); 

mais vous faites efficacement ceci:

SteamGobbler sg = new StreamGobbler(...); 
    Thread th = new Thread(sg); 
    th.start(); 
    th.join(); 

Il fonctionne ... mais seulement parce qu'un Threadest-unRunnable.

+0

Merci. L'exécution de cli renvoie la sortie complète. Appréciez les commentaires sur le sujet. C'est comme ça que je l'avais à l'origine, donc je l'ai inversé. – samiam

+0

@samiam - * "L'exécution de cli renvoie la sortie complète." *. Cela ne veut pas dire que ce n'est pas la faute du commandement externe. Les arguments de la ligne de commande ou les variables d'environnement peuvent être différents, etc. Vous devez vérifier le contenu de la commande stderr. –

Questions connexes