为什么我可以在写入Linux时成功移动Linux文件?

hal*_*fer 19 java linux filesystems android

我认为这个问题对于S/O来说足够技术,而且可能对于Android来说也是面向编程的.我对如何在Android(或Java或Linux,视情况而定)处理文件感到好奇,因为我用我的新智能手机做了一些事情,我很想知道它是如何发生的.

我正在通过蓝牙将文件从笔记本电脑传输到我的Android手机.我在文件资源管理器中看到了新文件,假设它已完全传输,因此将其/sdcard/bluetooth移至/sdcard/torrents.在我这样做之后,我注意到它实际上仍在被转移.令我惊讶的是,它已成功完成,通过电话上的通知图标确认,并通过双方手动MD5检查确认.在大多数系统中,文件移动会导致崩溃.

成功转移的原因是什么?我知道通常,文件路径与文件系统上的文件位置是分开的(在本例中是SD卡).我想蓝牙应用程序已经打开了文件的句柄,当我进行文件移动时,一个"打开文件"表被更新了一个新路径.这个功能通常适用于任何Linux系统吗?我可以mv对正在编写的文件执行操作,并希望副本 - 在新位置 - 是正确的吗?

Mat*_*Mat 39

同一文件系统中移动文件时,文件本身(inode)根本不会移动.唯一改变的是该文件系统中的目录条目.(mv在这种情况下调用的系统调用是rename(2)- 检查该页面以获取其他信息和限制.)

当进程打开文件时,文件名将传递给操作系统以指示哪个文件是什么意思,但是您获取的文件描述符根本没有链接到该名称(您无法从中获取文件名) - 它与inode相关联.
由于inode在重命名文件时(在同一文件系统内)保持不变,因此打开它的进程可以愉快地继续读取和写入 - 没有任何改变,它们的文件描述符仍然有效并指向正确的数据.

如果删除文件也一样.即使文件不再通过任何目录条目可访问,进程也可以继续读取和写入.(这可能导致df报告磁盘已满的混乱情况,但du表示您使用的df报告空间要少得多.分配给仍然打开的已删除文件的块在这些进程关闭其文件描述符之前不会被释放. )

如果mv跨文件系统移动文件,则行为是不同的,因为inode特定于每个文件系统.在这种情况下,mv实际上将复制数据,在目标文件系统上创建新的inode(和目录条目).复制结束后,旧文件将被取消链接,如果上面没有打开的文件句柄,则将其删除.
在您的情况下,如果您跨越了文件系统边界,则目标中将包含部分文件.并且您的上传过程很乐意写入您无法轻松访问的已删除文件,可能会填满该文件系统,直到上传完成,此时inode将被删除.

你会发现有趣的Unix和Linux上的一些帖子:

  • 很好的答案,谢谢Mat。是的,我正在一个文件系统中移动文件。我已经在类似Unix的系统上开发了几年,但是以前从未遇到过这种能力。我本来希望它会破坏编写器过程。很聪明的东西! (2认同)