我有以下代码:
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());
}
我不确定制作printer.flush();
是否是个好主意。我不知道为什么,但由于某种原因,我觉得它闻起来。我们将outputStream保持打开时间过长的原因之一。我们可以在externalHttpCall
调用之前将其关闭。
您能帮我解释一下吗?
我应该关闭流并仅然后执行externalHttpCall
吗?
为了提高I / O性能,操作系统会缓冲读取和写入操作。当您写入设备(例如磁盘)时,数据不会立即发送到设备,原因是会引起系统调用,这会产生开销。因此,操作系统会在用户空间中缓冲写操作。
请注意,内核空间中还有一个缓冲区,数据将从用户空间缓冲区复制到该缓冲区中(我们在上一段中讨论了用户空间缓冲区)。进行刷新时,用户空间缓冲区中剩余的所有数据都将复制到内核空间缓冲区中,并且该缓冲区变为空。这将导致系统调用。请注意,您仍然不能确保已写入磁盘。有多个系统调用(例如fsync
(..),可确保清空内核缓冲区并将其写入磁盘。
如果刷新速度太快,您将进行过多的系统调用,这会严重降低性能。我在某处阅读了一个实验,该实验表明4096B的缓冲区大小可提供最佳写入性能。对于您的情况,当您完成所有数据写入后,只需刷新一次即可。我认为这很好,完全不会降低您的性能。