1

I am using the object RandomAccessFile to access to files with

RandomAccessFile file = new RandomAccessFile(path, "r");

My problem is if file path get removed from disk when I do perform a

file.seek(...); 

or a

file.readLine()

no exception is started, I do not have any exception.

Is it possible to have an exception in case of Dangling Pointer, if this file has been removed from disk?

Is there another method to detect the file inaccessibility ?

4

2 回答 2

3

编辑:Windows 的精度(感谢 pingw33n)

在以下情况下你得到 no 是完全正常的Exception

  • 你打开一个文件
  • 您或其他人删除文件
  • 您仍然可以访问该文件,在删除之前读取它包含的内容,或写入它

事实上,删除文件对文件本身没有任何影响。删除的是目录中的条目。只有在以下情况下,文件才会真正被销毁(并且它在磁盘上使用的扇区将被释放):

  • 没有更多的目录条目指向它
  • 没有文件描述符保持打开

因此,即使您请求的字节没有缓冲在内存中,文件系统仍然知道如何从磁盘获取它。顺便说一句,创建临时文件是一种常见的模式,即在上次关闭时将被删除的文件。

当然,您可以按照 merlin2011 的建议进行操作,即通过路径测试文件是否存在。但是您必须知道,文件被删除然后再次创建,路径(用于打开文件)存在,但指向完全不同的对象。

因此,如果您确实需要该文件实际反映目录的内容,则不能保持打开状态,并且必须在每次访问时重新打开它......这不是一个公平的选择,您仍然可以:

  • 忽略对目录和文件系统的修改;你有一个文件,你使用它,句号。有许多用例是正确的。
  • 在您的文档中声明该目录是您的,其他人不应删除其中的文件。毕竟,您无法阻止管理员破坏其系统或杀死您的应用程序。

这适用于所有普通文件系统、Linux 或其他 Unix 系统、NTFS 等的所有文件系统。我不确定对于 CPM 或 FAT 等较旧的文件系统是否仍然适用,但它们目前已不再用于生产:-)。但是在 Windows 下,应该不可能删除当前在 java 应用程序中打开的文件。

准确回答您 2 个问题:

  • 你的指针没有悬空,但仍然指向一个真实的文件(即使没有其他人可以看到它)
  • 如果文件不可访问(磁盘或连接的物理损坏、文件系统错误等),将引发异常。但是,如果仅删除条目,该文件仍然可以访问
于 2014-06-17T20:05:56.667 回答
0

你的问题有两个答案。

  • 根据Javadoc,您应该得到一个IOExceptionif any byte 由于任何原因无法读取。

如果由于文件结尾以外的任何原因无法读取任何字节,则会引发除 EOFException 之外的 IOException。特别是,如果流已关闭,则可能会引发 IOException。

  • 您可以使用此答案中描述的方法在尝试读取之前显式检查文件删除。

    File f = new File(filePathString);
    if(f.exists() && !f.isDirectory()) { /* do something */ }
    
于 2014-06-17T18:27:03.573 回答