java - 读取另一个线程同时写入的文件流
问题描述
我有一个BlobInputStream
绑定到数据库事务的 Postgres,我需要将其传输到通过 HTTP 请求请求它的客户端。
为了避免慢速客户端饿死数据库事务,我想将流刷新到磁盘并同时让客户端从磁盘读取:这样,即使客户端仍在读取,事务也会在流写入磁盘时结束文件。
显然,我不希望客户端在开始读取之前等待整个流被刷新到磁盘。
到目前为止,这是我的代码:
public void transferStreamToChannel(InputStream stream, SinkChannel channel) {
try {
// Create a temporary file to buffer to stream transfer, so that slow readers won't
// starve the transaction.
var tmp = Files.createTempFile(StreamTransferInitiator.class.getSimpleName(),
Thread.currentThread().getName());
var tos = Files.newOutputStream(tmp);
var executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
try (var fis = Files.newInputStream(tmp, StandardOpenOption.DELETE_ON_CLOSE)) {
var out = Channels.newOutputStream(channel);
fis.transferTo(out);
} catch (IOException e) {
this.getLogger().error("Error writing to disk", e);
}
});
stream.transferTo(tos);
} catch (IOException e) {
this.getLogger().error("Error reading stream", e);
} finally {
try {
stream.close();
channel.close();
} catch (IOException e) {
this.getLogger().error("Error closing stream", e);
}
}
}
这样做的问题是执行程序会找到一个空文件,并且会在数据库流完全刷新之前关闭。
我怎样才能连接这两个操作,以便在传输到客户端时知道仍有更多数据要写入磁盘?