问题描述
现在来看一些OS函数,我发现在POSIX系统上,您有C函数调用,例如unlink()
删除文件,link()
创建文件的硬链接,symlink()
创建符号文件,rename()
移动文件,但是... copy()
文件的功能在哪里?
我知道通常的方法是只打开源文件,读取其内容,打开目标文件并将其转储到那里.但是,为什么在以前所有功能中都找不到这样的实用程序功能?
在谈论复制文件"时,存在两种语义:
- 深层复制-创建一个新文件,其中包含与该文件关联的所有数据/元数据的副本,但是文件系统对此进行了构建
- 浅拷贝-创建新的目录条目/文件,引用与源文件相同的数据(以及可能的部分或全部元数据)
Windows/DOS文件系统传统上没有任何浅表复制"机制-但UN * X始终具有硬链接形式.
因此POSIX/UN * X具有 link(2)
系统调用-建立一个以新名称对现有文件数据"的新引用-即执行浅拷贝.
仅当存在快速深层复制"机制时,深层复制"系统调用才有意义-例如,在底层文件系统实现诸如去重复的东西来进行文件级克隆的情况下.
否则,该函数将必须降级"(回退到)一个库实现.
UN * X机制允许文件系统特定的内容,例如ioctl()
,即"I/O可扩展性的厨房接收器".有关如何使用此功能(如果可用)复制文件的示例,请参见此GNU coreutils发布,并带有增强功能,要求在BTRFS上使用文件克隆.
鉴于Windows的CopyFile
实际上是没有回调的CopyFileEx
,我强烈怀疑这确实是系统调用;这是一个实用程序功能.对于 Wine Windows Emulator ,您可以检查kernel32.dll源实现,在Wine源中找到CopyFileEx
,举例说明该可以完成.
在Microsoft的许可下,不允许反汇编/反编译Windows的实际kernel.dll
,因此我不能合法地断言Windows本身也可以这样做,即CopyFile
是用户区实现,不是系统调用. /p>
要在此处再次比较Windows和UN * X ...而不是UN * X libc中的一切是系统调用,因此UN * X联机帮助页区分了第2节(系统调用)和第3节(运行时库接口). Windows中kernel.dll
中的函数也是如此-其中一些是直接传递",而另一些是更复杂的实用程序函数",这些功能不是通过单个系统调用实现的.
Looking now through some OS functions I find that on POSIX systems you have C function calls like unlink()
to remove files, link()
to create hard links to files, symlink()
to create symbolic files, rename()
to move a file, but ... where is a function to copy()
a file?
I know that the usual way is to just open the source file, read its contents, open a destination file and dump them there. But why can't I find any such utility function given all the previous ones?
When talking about "copying a file", two semantics exist:
- Deep Copy - the creation of a new file containing a copy of all data / metadata associated with the file, however the filesystem structures this
- Shallow Copy - the creation of a new directory entry/file referring to the same data (and possible some or all of the metadata) as the source file
Windows / DOS filesystems traditionally didn't have any "shallow copy" mechanism - but UN*X always had, in the form of hard links.
So POSIX/UN*X has the link(2)
system call - to establish a new reference to existing "file data" under a new name - i.e., do a shallow copy.
A "deep copy" system call only makes sense if there is a "fast deep copy" mechanism - for example, in cases where the underlaying filesystem implements something like deduplucation to do file-level cloning.
Otherwise, such a function would have to "degrade" (fall back to) a library implementation.
The UN*X mechanism to allow for something as filesystem-specific as this is ioctl()
, the "kitchen sink of I/O extensibility". For an example as how to use this facility, if available, to copy files, see this GNU coreutils post with an enhancement request to use file cloning on BTRFS.
Given that Windows' CopyFile
is actually CopyFileEx
without a callback, I strongly doubt it's really a system call; it's a utility function. For the Wine Windows Emulator, you can check the kernel32.dll source implementation, find CopyFileEx
in the Wine sources, dlls/kernel32/path.c
for an example how this can be done.
Disassembling / Decompiling Windows' actual kernel.dll
is not allowed under Microsoft's licensing, so I cannot legally assert that Windows itself does the same, i.e. CopyFile
is a userland implementation, not a system call.
To compare Windows and UN*X again here... not everything in UN*X libc is a system call, that's why the UN*X manpages distinguish between section 2 (sys calls) and section 3 (runtime library interfaces). The same is true for functions in kernel.dll
on Windows - some of them are "direct passthrough" while others are more complex "utility functions" not implemented via a single system call.
这篇关于有POSIX函数可以复制文件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!