gst*_*low 5 java io java-io apache-commons-csv
最初我有以下代码:
try (var output = new ByteArrayOutputStream();
var printer = new CSVPrinter(new OutputStreamWriter(output), CSVFormat.DEFAULT)) {
printer.printRecord(EMAIL);
for (MyBean mb : items) {
printer.printRecord(mb.getEmail());
}
externalHttpCall(output.toByteArray());
}
Run Code Online (Sandbox Code Playgroud)
在这里我发现有时字节数组没有完全写入。
我知道这是因为在externalHttpCall调用过程中没有刷新流。
为了修复它,我写了以下内容:
try (var output = new ByteArrayOutputStream();
var printer = new CSVPrinter(new OutputStreamWriter(output), CSVFormat.DEFAULT)) {
printer.printRecord(EMAIL);
for (MyBean mb : items) {
printer.printRecord(mb.getEmail());
}
printer.flush();
log.info("Printer was flushed");
externalHttpCall(output.toByteArray());
}
Run Code Online (Sandbox Code Playgroud)
它解决了这个问题,但在这里我迷失了一个想法,即仅在externalHttpCall. 所以我想出了以下解决方案:
externalHttpCall(convertToByteArray(items);
public byte[] convertToByteArray(List<MyBean> items){
try (var output = new ByteArrayOutputStream();
var printer = new CSVPrinter(new OutputStreamWriter(output), CSVFormat.DEFAULT)) {
printer.printRecord(EMAIL);
for (MyBean mb : items) {
printer.printRecord(mb.getEmail());
}
return output.toByteArray();
}
}
Run Code Online (Sandbox Code Playgroud)
我预计在流关闭之前会发生刷新。但根据我的实验,它不起作用。看起来这是因为刷新发生在流关闭之前但在 toByteArray 调用之后。
我怎么能修好呢?
鉴于问题中的三个代码片段,我认为这应该有效:
externalHttpCall(convertToByteArray(items);
public byte[] convertToByteArray(List<MyBean> items){
try (var output = new ByteArrayOutputStream();
var printer = new CSVPrinter(new OutputStreamWriter(output), CSVFormat.DEFAULT)) {
printer.printRecord(EMAIL);
for (MyBean mb : items) {
printer.printRecord(mb.getEmail());
}
printer.flush()
log.info("Printer was flushed");
return output.toByteArray();
}
}
Run Code Online (Sandbox Code Playgroud)
根据CSVFormat该CSVPrinter是在接近自动刷新(CSVFormat.DEFAULT不会自动刷新...)。您可以使用CSVFormat's builder like pattern 使格式在关闭时刷新CSVFormat.DEFAULT.withAutoFlush(true)(感谢@PetrBodnár 提供此提示)。然而,这在上面的例子中可能没有区别。
如果您将 try-with-resource 转换为实际的调用顺序,您将得到如下内容:
var output = new ByteArrayOutputStream();
var printer = new CSVPrinter(new OutputStreamWriter(output), CSVFormat.DEFAULT)
printer.printRecord(EMAIL);
...
var result = output.toByteArray();
printer.close(); // might call flush
output.close();
return result;
Run Code Online (Sandbox Code Playgroud)
由于关闭操作将在 finally 块中调用,因此它们将在创建字节数组后进行。如果需要刷新,则需要在调用toByteArray.