web-dev-qa-db-fra.com

Quand vider un BufferedWriter

Dans un programme Java (Java 1.5), j'ai un BufferedWriter qui enveloppe un Filewriter, et j'appelle write () plusieurs fois ... Le fichier résultant est assez gros ...

Parmi les lignes de ce fichier, certaines sont incomplètes ...

Dois-je appeler flush chaque fois que j'écris quelque chose (mais je soupçonne que cela serait inefficace) ou utiliser une autre méthode de BufferedWriter ou utiliser une autre classe ...?

(Comme j'ai un million de lignes à écrire, je veux quelque chose d'assez efficace.) Quel est le moment idéal pour "bouffer"? (quand j'atteins la capacité du BufferedWriter) ...

Init: 

try {
  analysisOutput = new BufferedWriter(new FileWriter(
      "analysisResults", true));
  analysisOutput.newLine();
  analysisOutput.write("Processing File " + fileName + "\n");
} 
catch (FileNotFoundException ex) {
  ex.printStackTrace();
} 
catch (IOException ex) {
  ex.printStackTrace();
}

L'écriture:

private void printAfterInfo(String toBeMoved,HashMap<String, Boolean> afterMap, Location location)
  throws IOException {
    if(afterMap != null) {
      for (Map.Entry<String, Boolean> map : afterMap.entrySet()) {
        if (toBeMoved == "Condition") {
          if (1 <= DEBUG)
            System.out.println("###" + toBeMoved + " " + location + " "
                + conditionalDefs.get(conditionalDefs.size() - 1)
                + " After " + map.getKey() + " "
                + map.getValue() + "\n");

          analysisOutput.write("###" + toBeMoved + " " + location + " "
              + conditionalDefs.get(conditionalDefs.size() - 1)
              + " After " + map.getKey() + " " + map.getValue()
              + "\n");
        } else {
          if (1 <= DEBUG)
            System.out.println("###" + toBeMoved + " " + location + " "
                + map.getKey() + " After " 
                + map.getValue() + "\n");
          if (conditionalDefs.size() > 0)
            analysisOutput.write("###" + toBeMoved + " " + location + " "
                + conditionalDefs.get(conditionalDefs.size() - 1) + " "
                + map.getKey() + " After " + map.getValue()
                + "\n");
          else
            analysisOutput.write("###" + toBeMoved + " " + location + " " + map.getKey() + " After " + map.getValue() + "\n");


        }
      }
    }

Je viens de comprendre que les lignes qui sont incomplètes sont celles juste avant "Processing file" ... cela se produit donc lorsque je bascule d'un fichier que j'analyse à un autre ...

Fermeture:

dispatch(unit);

try {
  if (analysisOutput != null) {
    printFileInfo();
    analysisOutput.close();
  }
} 
catch (IOException ex) {
  ex.printStackTrace();
}

Parfois, les informations imprimées par printFileInfo n'apparaissent pas dans le fichier de résultats ...

41
LB40

La BufferedWriter sera déjà vidée lorsqu'elle remplira sa mémoire tampon. À partir de la documentation de BufferedWriter.write :

Habituellement, cette méthode stocke les caractères du tableau donné dans la mémoire tampon de ce flux, vidage de la mémoire tampon dans le flux sous-jacent si nécessaire.

(Souligné par moi.)

Le but de BufferedWriter est en gros de regrouper beaucoup de petites écritures en beaucoup moins d'écritures de grande taille, car c'est généralement plus efficace (mais plus pénible à coder). Vous ne devriez pas avoir besoin de faire quelque chose de spécial pour le faire fonctionner correctement, mis à part vous assurer de le vider lorsque vous êtes terminé avec - et d'appeler close() le fera pour vider/fermer le sous-jacent. écrivain quand même. 

En d’autres termes, relaxez-vous d’écrire, écrivez, écrivez et fermez :) Le seul moment où vous devez normalement appeler flush manuellement est si vous avez vraiment, vraiment besoin que les données soient sur le disque. (Par exemple, si vous avez un enregistreur de données perpétuel, vous pouvez le vider de temps en temps afin que ceux qui lisent les journaux n'aient pas besoin d'attendre que la mémoire tampon soit pleine avant de pouvoir voir les nouvelles entrées de journal!)

83
Jon Skeet

Le moment idéal est quand vous avez besoin d'un autre programme qui lit le fichier pour voir les données qui ont été écrites, avant la fermeture du fichier. Dans de nombreux cas, ce n'est jamais.

11
Dave

Si vous avez une boucle alternant init et printAfterInfo, je suppose que votre problème est que vous n'avez pas close votre rédacteur avant d'en créer un nouveau sur le même fichier. Vous feriez mieux de créer la BufferedWriter une fois et de la fermer à la fin de tout le traitement.

0
laurent