6

我有一个临时文件,我想从 Play 框架中的控制器发送客户端。我可以在使用 FileInputStream 打开连接后删除文件吗?例如,我可以做这样的事情 -

File file = getFile();
InputStream is = new FileInputStream(file);
file.delete();
renderBinary(is, "name.txt");

如果文件是大文件怎么办?如果我删除文件,InputStream 上的后续 reads() 会出错吗?我尝试了大约 1MB 的文件,但没有收到错误消息。

抱歉,如果这是一个非常幼稚的问题,但我找不到与此相关的任何内容,而且我对 Java 还是很陌生

4

2 回答 2

2

我刚刚在我被要求处理的一些代码中遇到了完全相同的场景。程序员正在创建一个临时文件,在其上获取输入流,删除临时文件,然后调用 renderBinary。即使对于非常大的文件,它似乎也能正常工作,甚至达到千兆字节。

我对此感到惊讶,并且仍在寻找一些说明其工作原理的文档。

更新:我们终于遇到了一个导致这个东西爆炸的文件。我认为它超过 3 Gb。那时,有必要在渲染过程中不删除文件。我实际上最终使用了 Amazon Queue 服务来为这些文件排队消息。然后由计划的删除作业检索这些消息。效果很好,即使在负载平衡器上使用集群服务器。

于 2014-01-15T17:23:44.777 回答
1

删除文件后 FileInputStream 仍然可以读取,这似乎违反直觉。

DiskLruCache是 Android 世界里一个流行的库,起源于 Android 平台的libcore,甚至依赖于这个“特性”,如下所示:

// Open all streams eagerly to guarantee that we see a single published
// snapshot. If we opened streams lazily then the streams could come
// from different edits.
InputStream[] ins = new InputStream[valueCount];
try {
  for (int i = 0; i < valueCount; i++) {
    ins[i] = new FileInputStream(entry.getCleanFile(i));
  }
} catch (FileNotFoundException e) {
....

正如@EJP 在对类似问题的评论中指出的那样,“这就是 Unix 和 Linux 的行为方式。删除文件实际上是从目录中删除它的名称:inode 和数据在任何进程打开时仍然存在。”

但我不认为依赖它是一个好主意。

于 2016-03-02T10:00:15.433 回答