我编写了文件传输代码,如下所示:

val fileContent: Enumerator[Array[Byte]] = Enumerator.fromFile(file)
val size = file.length.toString
file.delete // (1) THE FILE IS TEMPORARY SO SHOULD BE DELETED
SimpleResult(
 header = ResponseHeader(200, Map(CONTENT_LENGTH -> size, CONTENT_TYPE -> "application/pdf")),
 body = fileContent)

即使文件很大(2.6 MB),此代码也可以成功运行,
但是我很困惑,因为我对.fromFile()的理解是fromCallBack()的包装,而SimpleResult实际上读取了buffed的文件,但是在此之前该文件已被删除。

我的简单假设是java.io.File.delete等到块读取完成后才释放文件,但是我从未听说过Java File类的过程,
或者.fromFile()已经将所有行都加载到Enumerator实例中,但是我认为这违反了fromCallBack()规范。

有人知道这种机制吗?

最佳答案

我猜您在某种Unix系统上,例如OSX或Linux。

在Unix:y系统上,您实际上可以删除打开的文件,任何文件系统条目都只是指向实际文件的链接,打开文件时获得的文件句柄也是如此。在删除文件的最后一个链接之前,文件内容不会变得无法访问/删除。

因此:在执行file.delete之后,它将不再显示在文件系统中,但是您仍然可以使用Enumerator.fromFile(file)中创建的InputStream读取它,因为它创建了文件句柄。 (在Linux上,您实际上可以通过特殊的/ proc文件系统找到它,该文件系统除其他外还包含每个运行进程的文件句柄)

在Windows上,我认为您会收到错误消息,因此,如果要在多个平台上运行,则可能还要检查在Windows上测试您的Web应用程序。

10-04 10:49