IOException:关闭文件流时权限被拒绝
IOException: Permission denied when closing file stream
在远程机器上,我观察到无法重现或解释的异常。
同样的过程 运行 多年来一直没有问题。正在从 SCP 下载多个类似文件到 RedHat Linux 上的共享网络位置,磁盘上肯定有空闲 space,所有权限都很好。只有几个文件描述符打开。今天,突然间,在写入最后一个文件时 java.io.IOException: Permission denied
在 关闭 流时出现,但文件已正确保存。
这种异常的可能原因是什么? 除了 Permission denied
到 [= 的映射之外,我在 Java 源代码中没有找到任何内容13=]。在浏览互联网时,我只发现人们在打开流时得到 Permission denied
但没有关闭它的情况。
java.io.IOException: Permission denied
at java.io.FileOutputStream.close0(Native Method)
at java.io.FileOutputStream.access[=10=]0(FileOutputStream.java:53)
at java.io.FileOutputStream.close(FileOutputStream.java:356)
at java.io.FileDescriptor.closeAll(FileDescriptor.java:212)
at java.io.FileOutputStream.close(FileOutputStream.java:354)
at java.io.FilterOutputStream.close(FilterOutputStream.java:159)
at com.aestasit.ssh.dsl.ScpMethods.doGet(ScpMethods.groovy:249)
at com.aestasit.ssh.dsl.ScpMethods.this$doGet(ScpMethods.groovy)
at com.aestasit.ssh.dsl.ScpMethods.download(ScpMethods.groovy:162)
at com.aestasit.ssh.dsl.SshDslEngine.executeSession(SshDslEngine.groovy:70)
at com.aestasit.ssh.dsl.SshDslEngine$remoteSession.call(Unknown Source)
at com.aestasit.ssh.DefaultSsh.remoteSession(DefaultSsh.groovy:46)
at com.aestasit.ssh.DefaultSsh$remoteSession.callStatic(Unknown Source)
这只是一个理论....
查看 Linux 内核源代码,似乎在某些情况下 close(fd)
系统调用会在关闭前尝试进行内部刷新。如果 fd
与 "file system" 上的文件相关联,其中可以在文件打开时更改有效访问权限,那么可以想象关闭的刷新可能会失败,因为 当前 权限限制太多。那会变成 EACCES 系统调用失败。
这样的故障很少见,因为文件的权限仅在 "right" 时间发生变化而触发故障的情况很少见;即在 close
系统调用和之前的 write
系统调用之间。
此外,可以想象这只会发生在某些类型的文件上;例如远程文件服务器上的文件,由远程服务器实现访问控制。
请注意,Linux 手动输入或 POSIX 规范并未设想 close()
因 EACCES 而失败。文档暗示只有在打开文件时才会检查访问权限,这是(至少)是意外行为。
然而,不利的一面是(虚拟)文件系统行为的各个方面取决于文件系统本身的实现。在少数情况下,文件系统不正常 "normally".
在远程机器上,我观察到无法重现或解释的异常。
同样的过程 运行 多年来一直没有问题。正在从 SCP 下载多个类似文件到 RedHat Linux 上的共享网络位置,磁盘上肯定有空闲 space,所有权限都很好。只有几个文件描述符打开。今天,突然间,在写入最后一个文件时 java.io.IOException: Permission denied
在 关闭 流时出现,但文件已正确保存。
这种异常的可能原因是什么? 除了 Permission denied
到 [= 的映射之外,我在 Java 源代码中没有找到任何内容13=]。在浏览互联网时,我只发现人们在打开流时得到 Permission denied
但没有关闭它的情况。
java.io.IOException: Permission denied
at java.io.FileOutputStream.close0(Native Method)
at java.io.FileOutputStream.access[=10=]0(FileOutputStream.java:53)
at java.io.FileOutputStream.close(FileOutputStream.java:356)
at java.io.FileDescriptor.closeAll(FileDescriptor.java:212)
at java.io.FileOutputStream.close(FileOutputStream.java:354)
at java.io.FilterOutputStream.close(FilterOutputStream.java:159)
at com.aestasit.ssh.dsl.ScpMethods.doGet(ScpMethods.groovy:249)
at com.aestasit.ssh.dsl.ScpMethods.this$doGet(ScpMethods.groovy)
at com.aestasit.ssh.dsl.ScpMethods.download(ScpMethods.groovy:162)
at com.aestasit.ssh.dsl.SshDslEngine.executeSession(SshDslEngine.groovy:70)
at com.aestasit.ssh.dsl.SshDslEngine$remoteSession.call(Unknown Source)
at com.aestasit.ssh.DefaultSsh.remoteSession(DefaultSsh.groovy:46)
at com.aestasit.ssh.DefaultSsh$remoteSession.callStatic(Unknown Source)
这只是一个理论....
查看 Linux 内核源代码,似乎在某些情况下 close(fd)
系统调用会在关闭前尝试进行内部刷新。如果 fd
与 "file system" 上的文件相关联,其中可以在文件打开时更改有效访问权限,那么可以想象关闭的刷新可能会失败,因为 当前 权限限制太多。那会变成 EACCES 系统调用失败。
这样的故障很少见,因为文件的权限仅在 "right" 时间发生变化而触发故障的情况很少见;即在 close
系统调用和之前的 write
系统调用之间。
此外,可以想象这只会发生在某些类型的文件上;例如远程文件服务器上的文件,由远程服务器实现访问控制。
请注意,Linux 手动输入或 POSIX 规范并未设想 close()
因 EACCES 而失败。文档暗示只有在打开文件时才会检查访问权限,这是(至少)是意外行为。
然而,不利的一面是(虚拟)文件系统行为的各个方面取决于文件系统本身的实现。在少数情况下,文件系统不正常 "normally".