在 Linux 上用 C 移动文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17438493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Moving a file on Linux in C
提问by John Vulconshinz
- Platform: Debian Wheezy 3.2.0-4-686-pae
- Complier: GCC (Debian 4.7.2-5) 4.7.2 (Code::Blocks)
- 平台:Debian Wheezy 3.2.0-4-686-pae
- 编译器:GCC (Debian 4.7.2-5) 4.7.2 (Code::Blocks)
I want to move a file from one location to another. Nothing complex like moving to different drives or to different file systems. I know the "standard" way to do this would be simply copying the file and then removing the original. But I want some way of preserving the file's ownership, mode, last access/modification, etc. . I am assuming that I will have to copy the file and then edit the new file's ownership, mode, etc. afterwards but I have no idea how to do this.
我想将文件从一个位置移动到另一个位置。没有什么比移动到不同的驱动器或不同的文件系统更复杂的了。我知道执行此操作的“标准”方法是简单地复制文件,然后删除原始文件。但我想要某种方式来保留文件的所有权、模式、上次访问/修改等。我假设我必须复制文件,然后编辑新文件的所有权、模式等,但我不知道如何执行此操作。
采纳答案by Basile Starynkevitch
If you cannot use the rename(2)syscall (e.g. because source and target are on different filesystem), you have to query the size, permission and other metadata of the source file with stat(2); copy the data using read(2), write(2)(using a buffer of several kilobytes), open(2), close(2)and the metadata using chmod(2), chown(2), utime(2). You might also care about copying attributes using getxattr(2), setxattr(2), listxattr(2). You could also in some cases use sendfile(2), as commented by David C. Rankin.
如果您不能使用rename(2)系统调用(例如,因为源和目标在不同的文件系统上),则必须使用stat(2)查询源文件的大小、权限和其他元数据;使用read(2)、write(2)(使用几千字节的缓冲区)、open(2)、close(2)复制数据,并使用chmod(2)、chown(2)、utime(2) 复制元数据。您可能还关心使用getxattr(2)、setxattr(2)、listxattr(2)复制属性。您也可以在某些情况下使用sendfile(2),如评论 大卫 C. 兰金。
And if the source and target are on different filesystems, there is no way to make the move atomic and avoid race conditions (So using rename(2)is preferable when possible, because it is atomic according to its man page). The source file can always be modified (by another process) during the move operations...
如果源和目标位于不同的文件系统上,则无法使移动原子化并避免竞争条件(因此,最好尽可能使用rename(2),因为根据其手册页,它是原子的)。在移动操作期间,源文件总是可以被修改(由另一个进程)...
So a practical way to move files is to first try doing a rename(2), and if that fails with EXDEV
(when oldpathand newpathare not on the same mounted filesystem), then you need to copy bytes and metadata. Several libraries provide functions doing that, e.g. Qt QFile::rename.
因此,移动文件的一种实用方法是首先尝试执行rename(2),如果失败EXDEV
(当oldpath和newpath不在同一个挂载的文件系统上时),那么您需要复制字节和元数据。一些库提供了这样做的函数,例如 Qt QFile::rename。
Read Advanced Linux Programmingfor more (and also try to strace
some mv
command to understand what it is doing). That book is freely and legally downloadable (so you could find several copies on the Web).
阅读高级 Linux 编程了解更多信息(并尝试使用strace
一些mv
命令来了解它在做什么)。那本书可以免费且合法地下载(因此您可以在网上找到几本)。