かなり前に書いたCSV書込み、渡している OutputStream はやはり呼び出し側で行った方が良い。
前に書いたもの、、つい try リソースハンドラの close で書いてしまった。
CSV書込み(2) - Oboe吹きプログラマの黙示録
書き直すと、、
import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Serializable; import java.util.Arrays; import java.util.Collection; import java.util.function.Supplier; import java.util.stream.Collectors; import net.sf.csv4j.CSVWriter; /** * CSV生成インターフェース. */ @FunctionalInterface public interface CsvCreator extends Serializable{ /** * CSV出力行数分の Colleactionを返す Supplier を取得する. * @return Supplier<Collection<String[]> */ public Supplier<Collection<String[]>> getSupplier(); /** * CSV出力実行. (注意:OutputStream は 呼出し側で closeすること) * @param out OutputStream * @param charName 文字セット名 */ default public void create(OutputStream out, String charName){ try{ OutputStreamWriter writer = new OutputStreamWriter(out, charName); CSVWriter csvWriter = new CSVWriter(writer); for(String[] s:getSupplier().get()){ for(int i=0;i < s.length;i++){ s[i] = s[i]==null ? "" : s[i]; } csvWriter.writeLine(s); } writer.flush(); }catch(Exception e){ throw new RuntimeException(e.getMessage(), e); } } /** * ダブルクォート括りCSV出力実行. (注意:OutputStream は 呼出し側で closeすること) * @param out OutputStream * @param charName 文字セット名 */ default public void createWithDblQuot(OutputStream out, String charName){ String lineSeparator = System.getProperty("line.separator"); try{ OutputStreamWriter writer = new OutputStreamWriter(out, charName); for(String[] sary:getSupplier().get()){ for(int i=0;i < sary.length;i++){ sary[i] = sary[i]==null ? "" : sary[i]; } writer.write(csvline(sary)); writer.write(lineSeparator); } writer.flush(); }catch(Exception e){ throw new RuntimeException(e.getMessage(), e); } } default public String csvline(String[] ary){ return "\"" + Arrays.stream(ary).map(s->s.replaceAll("\"","\"\"")).collect(Collectors.joining("\",\"")) + "\""; } }
複数のCSV出力→ZIP圧縮の時に、呼び出し側でCLOSEするようにしないと困るのだ。
try(ZipOutputStream zos = new ZipOutputStream(out)){ CsvCreator c; zos.putNextEntry(new ZipEntry("a.csv")); // list は、CSV出力する List<String[]> c = ()->()->list; c.createWithDblQuot(zos, "MS932"); zos.flush(); zos.putNextEntry(new ZipEntry("b.csv")); c = ()->()->list; c.createWithDblQuot(zos, "MS932"); zos.flush();