linux - 在Unix中删除文件后为什么可以访问文件?

标签 linux file unix filesystems

我想到了一个并发问题(Solaris中的),如果在读取某人试图删除同一文件时会发生什么。我有一个关于 Solaris/Linux 中文件存在的查询。假设我有一个文件test.txt,我在vi编辑器中打开了,然后打开了一个重复 session ,然后删除了该文件的,但是即使删除了该文件,我仍然可以读取该文件。所以这是我的问题:

  • 在读取时是否需要考虑任何锁定机制,因此没有人能够在读取时删除同一文件。
  • 显示与Windows不同行为的原因是什么(例如在Windows中,如果在某些编辑器中打开文件而不是我们无法删除该文件)
  • 删除该文件后,如果我还没有从vi编辑器中关闭文件,我仍然能够读取该文件。

  • 我通常询问的是文件,但是是平台特定的,即和unix 。如果我使用Java程序(缓冲区读取器)读取文件,并且在读取时删除了文件,缓冲区读取器是否仍可以读取下一个块的文件会发生什么?

    最佳答案

    那里基本上有2或3个无关的问题。文本编辑器喜欢在编辑 session 开始时将整个文件读入内存。想象一下,您键入的每个字符都会立即保存到磁盘中,文件中的所有字符都将被重写一处,以腾出空间。那太可怕了。更好的是,您实际上正在编辑的是文件的内存表示形式(指向行的指针的数组,可能附加了一些元数据),只有在您明确保存时才将其转换回线性流。

    任何相对较新版本的vim都会通知您,如果您正在编辑的文件已从原始位置删除,并显示以下消息

    E211: File "filename" no longer available
    

    此警告不仅针对Unix。如果您删除正在编辑的文件,Windows上的gvim会为您提供。它提醒您,如果您不想丢失文件,则需要在退出之前保存正在处理的版本。

    (注意:警告不会立即出现-vim仅在离开原始文件后将其放回前台时才检查原始文件的存在。)

    这就是问题1,文本编辑器的行为-没有理由让他们在整个 session 中保持文件打开状态,因为除了启动和保存操作外,他们实际上并未使用该文件。

    问题2,为什么某些Windows编辑器使文件保持打开和锁定状态-我不知道,Windows人士对此感到很困惑。

    问题3,实际上是关于unix的问题,为什么打开的文件在删除后仍然可以访问-这是最有趣的一个。直接给出答案,一定会让您震惊:

    没有命令,函数,系统调用或其他任何实际要求删除文件的方法。

    rm和可能会删除文件的其他任何命令的基础上,有一个系统调用unlink。它被称为unlink,而不是removedeletefile或类似名称,因为它不会删除文件。它将删除链接(也称为目录条目),该链接是文件和目录中名称之间的关联。 (注:ANSI C添加了remove作为更通用的函数,以安抚无意于实现unix文件系统语义的非Unix用户,但是在unix上,如果目标是目录,则remove只是rmdir,而其他所有内容则是unlink。 )

    一个文件可以具有多个链接(有关如何创建的信息,请参见ln命令),这意味着同一文件可以被多个名称识别。如果您用rm编码其中的一个,则其他编码仍然存在,并且不会删除该文件。删除最后一个链接会怎样?好了,现在您有了一个没有名称的文件。但是名称只是对文件的一种引用。至少还有两个:文件描述符和mmap区域。当最后一个文件引用消失时,即删除该文件。

    由于引用以多种形式出现,因此有多种事件可以导致文件被删除。这里有些例子:
  • 取消链接(rm等)
  • 关闭文件描述符
  • dup2(可以在将文件描述符替换为其他文件描述符的副本之前隐式关闭文件描述符)
  • exec(可以通过close-on-exec标志关闭文件描述符)
  • munmap(取消映射内存区域)
  • mmap(如果在已经映射的地址上创建新的内存映射,则旧映射将不被映射)
  • 进程终止(关闭所有文件描述符并取消映射进程的所有内存映射)
  • 正常退出
  • 内核(^ C,segfault)生成的
  • 致命信号
  • 另一个进程发送的
  • 致命信号(杀死)

  • 我不会称其为完整 list 。而且我不鼓励任何人尝试构建完整列表。只需知道rm是“删除名称”,而不是“删除文件”,并且文件在不使用时就会消失。

    如果要立即销毁文件的内容,请截断它。所有已经使用它的进程都会发现它的大小突然变为0。(就普通的文件访问方法而言,这是销毁。要更彻底地销毁它,以至于即使具有原始磁盘访问权限的人也无法读取过去的文件在那里,您需要覆盖它。有一个名为shred的工具。)

    关于linux - 在Unix中删除文件后为什么可以访问文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22246397/

    相关文章:

    linux - 通过家庭网络流式传输高清视频

    arrays - 通过 HTTP 将文件下载到 C# 中的字节数组中?

    c - Unix 中的 'whiteout' (S_IFWHT) 是什么?

    linux - 查找以数字开头的目录数

    linux - 找不到包 'libxml-2.0'

    c++ - SDL 在 1920x1080 上设置窗口显示模式

    linux - 如何在字符串中查找子字符串(或如何 grep 变量)?

    c - 搜索文件中的元素并打印整行

    linux - 为什么linux用户空间和内核空间的代码运行速度会有差异?

    java - 从外部 Jar 文件内部读取文件?