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

时间:2012-08-05 18:04:57

标签: java android linux filesystems

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

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

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

1 个答案:

答案 0 :(得分:36)

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

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

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

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

Unix & Linux上的一些您可能感兴趣的帖子: