简体   繁体   English

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

[英]Why can I successfully move a file in Linux while it is being written to?

This question I think is technical enough for Stack Overflow, and probably too programming-oriented for Android .我认为这个问题对于 Stack Overflow 来说已经足够技术了,而且对于Android来说可能太面向编程了。 I am intrigued as to how files are handled in Android (or Java or Linux, as appropriate), since I did something with my new smartphone and I'd curious to know how it happened.我对 Android(或 Java 或 Linux,视情况而定)如何处理文件很感兴趣,因为我用我的新智能手机做了一些事情,我很想知道它是如何发生的。

I was transferring a file from my laptop to my Android phone, via Bluetooth.我正在通过蓝牙将文件从我的笔记本电脑传输到我的 Android 手机。 I saw the new file in the file explorer, assumed it was fully transferred, and so moved it from /sdcard/bluetooth to /sdcard/torrents .我在文件资源管理器中看到了新文件,假设它已完全传输,因此将其从/sdcard/bluetooth移至/sdcard/torrents After I had done so, I noticed it was in fact still being transferred.这样做之后,我注意到它实际上仍在转移。 To my surprise, it completed successfully, confirmed with a notification icon on the phone, and by a manual MD5 check on both sides.令我惊讶的是,它成功完成,通过手机上的通知图标确认,并通过双方的手动 MD5 检查确认。 In most systems, the file move would have caused a crash.在大多数系统中,文件移动会导致崩溃。

What is the reason for this successful transfer?这次转账成功的原因是什么? I'm aware that in general, the file path is separate to the file location on the file system (in this case, an SD card).我知道一般来说,文件路径与文件系统(在本例中为 SD 卡)上的文件位置是分开的。 I imagine that the Bluetooth app has opened a handle to the file, and when I did the file move, a table of 'open files' was updated with a new path.我想象蓝牙应用程序已经打开了文件的句柄,当我移动文件时,“打开文件”表已更新为新路径。 Is this feature generally true of any Linux system?此功能是否普遍适用于任何 Linux 系统? Could I do a mv on a file being written and expect the copy - in its new location - to be correct?我可以对正在写入的文件执行mv并期望副本(在其新位置)是正确的吗?

When you move a file inside the same filesystem , the file itself (the inode ) isn't moved at all.当您在同一文件系统中移动文件时,文件本身(索引节点)根本不会移动。 The only thing that changes are the directory entries in that filesystem.唯一改变的是该文件系统中的目录条目。 (The system call invoked by mv in this case is rename(2) - check that page for additional information and restrictions.) (在这种情况下由mv调用的系统调用是rename(2) - 检查该页面以获取更多信息和限制。)

When a process opens a file, the filename is passed to the OS to indicate which file is meant, but the file descriptor you get back isn't linked to that name at all (you can't get back a filename from it) – it is linked to the inode.当一个进程打开一个文件时,文件名被传递给操作系统以指示它是哪个文件,但是你得到的文件描述符根本没有链接到那个名字(你不能从它取回文件名) –它链接到索引节点。
Since the inode remains unchanged when you rename a file (inside the same filesystem), processes that have it open can happily keep reading from and writing to it – nothing changed for them, their file descriptor is still valid and pointing to the right data.由于重命名文件时 inode 保持不变(在同一文件系统内),因此打开它的进程可以愉快地继续读取和写入它——它们没有任何变化,它们的文件描述符仍然有效并指向正确的数据。

Same thing if you delete a file.如果你删除一个文件也是一样的。 Processes can keep reading and writing from it even if the file is no longer reachable through any directory entry.即使无法再通过任何目录条目访问该文件,进程也可以继续从中读取和写入。 (This can lead to confusing situations where df reports that your disk is full, but du says you're using much less space that df reports. The blocks assigned to deleted files that are still open won't be released until those processes close their file descriptor.) (这可能会导致令人困惑的情况, df报告您的磁盘已满,但du说您使用的空间比df报告的要少得多。分配给仍处于打开状态的已删除文件的块将不会被释放,直到这些进程关闭它们的文件描述符。)

If the mv moves the file across filesystems, then the behavior is different since inodes are specific to each filesystem.如果mv跨文件系统移动文件,那么行为是不同的,因为 inode 特定于每个文件系统。 In that case, mv will actually copy the data over, creating a new inode (and directory entry) on the destination filesystem.在这种情况下, mv实际上会复制数据,在目标文件系统上创建一个新的 inode(和目录条目)。 When the copy is over, the old file is unlinked, and removed if there are no open filehandles on it, as above.复制结束后,旧文件将取消链接,如果上面没有打开的文件句柄,则将其删除,如上所述。
In your case, if you had crossed a filesystem boundary, you'd have a partial file in the destination.在您的情况下,如果您跨越了文件系统边界,则目标中会有一个部分文件。 And your upload process happily writing to a deleted file you can't easily access, possibly filling up that filesystem, until the upload finished at which point the inode would get dropped.并且您的上传过程愉快地写入您无法轻松访问的已删除文件,可能会填满该文件系统,直到上传完成,此时 inode 将被删除。

Some posts on Unix & Linux that you could find interesting:您可能会发现一些关于Unix 和 Linux的有趣帖子:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM