2017-10-16 3 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

에서 당신은 시도 -과 - 자원이 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 : 프린터를 반환 할 경우

그래서, 다음 자원

으로 시도 자세한 내용은이 질문에서보세요 사용하지 말아 귀하의 필요에 맞게. 시도해보십시오 ... –

1

이 발생하는 오류는 Try-with-resources-statement의 missinterpretation입니다. 당신의 시도 블록은 다음 CSVPrinterFileWriter 및 개방하고있는

:

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

전 완전히 그렇게 할 수 있습니다. 하지만 스트림이 닫히는 것을 어떻게 보장 할 수 있을까요? 작가는 주요 범위에서 액세스 할 수 없으므로 메인 메서드의 범위에서 finally 블록의 프린터를 닫으려고 할 수도 있습니다. 이렇게하면 하천의 적절한 폐쇄가 보장 될까요? –

+0

@sophist_pt 가장 쉬운 방법은'getCSVPrinter()'메소드 전체를 제거하고 코드가 사용 된 곳으로 붙여 넣는 것입니다. 그렇지 않으면 그냥 불필요한 많은 작업을 할 수 있습니다. – Lino

관련 문제