为什么这段代码与Enumerator.fromFile一起成功运行?

时间:2013-04-17 09:47:30

标签: scala playframework playframework-2.0

我写的文件传输代码如下:

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实际上是读取文件buffred,但文件在此之前被删除。

我很容易假设java.io.File.delete在块读取完成后等待文件释放,但我从未听说过Java File类的进程, 或者.fromFile()已经将所有行加载到Enumerator实例,但我认为它与fromCallBack()规范相反。

有人知道这种机制吗?

1 个答案:

答案 0 :(得分:2)

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

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

所以:在你执行file.delete之后它将不再出现在文件系统中,但你仍然可以使用在Enumerator.fromFile(file)中创建的InputStream来读取它,因为它创建了一个文件句柄。 (在Linux上,您实际上可以通过特殊的/ proc文件系统找到它,其中包含每个正在运行的进程的文件句柄)

在Windows上我认为你会收到一个错误,所以如果要在多个平台上运行,你应该检查一下你在windows上测试你的webapp。