2017-10-16 20 views
0

Je passe dans une imprimante CSVPrinter dans une méthode et en interne dans une boucle j'appelle la méthode printRecord. Voici l'extrait de la méthode.CSVPrinter printRecord java.io.IOException: Stream fermé

private void printToCsv(String currentDate, LinkedHashMap<String, LinkedList<CMonthlyStats>> contracts, CSVPrinter printer){ 
    List<String> activeContracts = ContractMonthlyStatsReader.getListOfActiveContracts(currentDate, contrs); 
    for (String activeContract: activeContracts){ 

    CMonthlyStatsR report = getCMonthlyStatsR(currentDate, activeContr, contracts.get(activeContr)); 
     try { 
     printer.printRecord(
      report.getAID(), 
      report.getMD(), 

      report.getAL(), report.getEL(), 
      ReportUtil.getMatchValue(), 

      report.getAFL(), report.getEFL(), 
      ReportUtil.getMatchValue(), 

      report.getAPF(), report.getEPF(), 
      ReportUtil.getMatchValue() 
     ); 
     printer.flush(); 
     } 

     catch (IOException e) { 
     e.printStackTrace(); 
     } 

    } 
    } 

L'imprimante est en cours d'initialisation par une autre méthode dans la principale méthode de la façon suivante:

public void Main(){ 
..... 
    CSVFormat format = getformatWithHeaders(); 
    final CSVPrinter printer = getCSVPrinter(format); 
..... 
    for(String string: Strings){ 
     ....... 
     printToCsv(currentDate, contrs, printer); 

     ....... 
    } 
} 

Snippet de getCSVPrinter (format) Méthode:

private CSVPrinter getCSVPrinter(CSVFormat format){ 
    try (final FileWriter newWriter = new FileWriter(System.getProperty("output.file"))){ 
     try(final CSVPrinter printer = new CSVPrinter(newWriter, format)){ 
     return printer; 
     } 
    } 
    catch (IOException e){ 
     e.printStackTrace(); 
    } 
    return null; 
    } 

Les impressions en-tête à le fichier de sortie, mais chaque fois qu'un enregistrement essaie d'être imprimé, je reçois java.io.IOException: Stream closed. La manipulation des OI a toujours été un cauchemar pour moi. S'il vous plaît aider!

Le CSVPrinter est de org.apache.commons.csv

Répondre

1

Vous utilisez la fonctionnalité dans votre getCSVPrinter -method essayer avec-ressources. Il ferme automatiquement le flux si vous quittez ce bloc.

try(final CSVPrinter printer = new CSVPrinter(newWriter, format)){ 
    return printer; 
} 

Une solution consiste à retirer le bloc try et juste revenir new CSVPrinter(newWriter, format). Mais alors vous devez fermer le ruisseau après vos opérations vous-même. Une autre solution serait de faire toute votre gestion de flux dans le bloc try-with-resources. Voici un exemple qui utilise l'interface client pour écrire dans CsvPrinter dans le bloc try-with-resources.

public void Main(){ 
    ..... 
    CSVFormat format = getformatWithHeaders(); 
    ..... 
    for(String string: Strings){ 
     ....... 
     printToCsv(currentDate, contrs, format); 
     ....... 
    } 
} 

private void printToCsv(String currentDate, LinkedHashMap<String, LinkedList<CMonthlyStats>> contracts, CSVFormat format){ 
    List<String> activeContracts = ContractMonthlyStatsReader.getListOfActiveContracts(currentDate, contrs); 
    for (String activeContract: activeContracts){ 

    CMonthlyStatsR report = getCMonthlyStatsR(currentDate, activeContr, contracts.get(activeContr)); 
    printToCSV(format, printer -> { 
     try { 
      printer.printRecord(
       report.getAID(), 
       report.getMD(), 

       report.getAL(), report.getEL(), 
       ReportUtil.getMatchValue(), 

       report.getAFL(), report.getEFL(), 
       ReportUtil.getMatchValue(), 

       report.getAPF(), report.getEPF(), 
       ReportUtil.getMatchValue() 
      ); 
      printer.flush(); 
      } 

      catch (IOException e) { 
      e.printStackTrace(); 
      } 
     }); 
    } 
} 

private void printToCSV(CSVFormat format, Consumer<CSVPrinter> consumer){ 
    try (final FileWriter newWriter = new FileWriter(System.getProperty("output.file"))){ 
     try(final CSVPrinter printer = new CSVPrinter(newWriter, format)){ 
     consumer.accept(printer); 
     } 
    } 
    catch (IOException e){ 
     e.printStackTrace(); 
    } 
} 
+0

@sophist_pt J'ai ajouté un exemple qui utilise une expression de lamda pour répondre à vos besoins. Avoir un essai ... –

1

L'erreur que vous rencontrez est un missinterpretation du Try-with-resources-statement.

dans vos blocs try vous ouvrez un FileWriter puis un CSVPrinter:

try (final FileWriter newWriter = new FileWriter(System.getProperty("output.file"))){ 
    try(final CSVPrinter printer = new CSVPrinter(newWriter, format)){ 
    return printer; 
    } 
} 
catch (IOException e){ 
    e.printStackTrace(); 
} 

mais quand vous retournez l'imprimante, il accapare déjà fermé, parce que l'essai avec-ressources instruction est fermée.

Donc, si vous voulez retourner l'imprimante, puis ne l'employez pas essayer avec les ressources

Jetez un oeil à cette question pour plus d'informations: https://stackoverflow.com/a/22947904/5515060

+0

Je pourrais totalement faire cela. Mais comment ferais-je pour que le courant soit fermé? Parce que l'écrivain ne serait pas accessible dans le champ d'application principal. Je pensais peut-être que je pourrais juste essayer de fermer l'imprimante dans le bloc finalement dans la portée de la méthode principale. Est-ce que cela assurerait la bonne fermeture du cours d'eau? –

+0

@sophist_pt le plus simple est de supprimer toute la méthode 'getCSVPrinter()' et de simplement coller votre code là où il est utilisé. Sinon, vous avez beaucoup de travail, ce qui semble inutile – Lino