2017-10-16 244 views
0

我传入一个CSVPrinter打印机的方法和内部循环我正在调用printRecord方法。以下是该方法的片段。CSVPrinter printRecord java.io.IOException:流关闭

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

    } 
    } 

打印机正在被另一个方法中以下列方式的主要方法初始化:

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

     ....... 
    } 
} 

片段getCSVPrinter(格式)的方法:

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

页眉打印到输出文件,但每次有记录正在尝试打印时,我得到java.io.IOException: Stream closed。处理IO一直是我的噩梦。请帮忙!

的CSVPrinter是org.apache.commons.csv

回答

1

您使用try-与资源在getCSVPrinter -method功能。如果您离开此块,它会自动关闭流。

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

一种解决方法是移除try块,就回到new CSVPrinter(newWriter, format)。但是你必须自己关闭你的操作后的流。

另一个解决方案是在try-with-resources-block内完成所有的流处理。


这是一个使用消费者接口在try-with-resources-block中写入CsvPrinter的示例。

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我添加了一个例子,它使用一个LAMDA表达式以适应您的需求。试试看... –

1

您遇到的错误是Try-with-resources-statement的错误解释。

在try块你打开一个 FileWriter然后 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(); 
} 

,但是当你回到它已经被关闭打印机,因为试穿与资源语句被关闭。

所以,如果你想返回的打印机,然后不使用尝试用资源

看一看这个问题的详细资料:https://stackoverflow.com/a/22947904/5515060

+0

我完全可以做到这一点。但是,我将如何确保该流被封闭。因为作者在主要范围内不可访问。我想也许我可以试着在main方法的范围内的finally块中关闭打印机。这将确保正确关闭流? –

+0

@sophist_pt最简单的方法是删除整个'getCSVPrinter()'方法,并将代码粘贴到它使用的位置。否则你会得到很多工作,这似乎没有必要 – Lino