Answers:
macos具有/.vol/
映射到实际目录和文件的特殊系统。/.vol/<device_id>/<inode_number>
无论文件在文件系统上的什么位置,都可以通过访问文件和目录。
这是一个很好的小系统。
因此,程序可以例如获取inode号,/Users/jdoe/someFile.txt
然后通过来打开它/.vol/12345/6789
(在这种情况下,设备ID为12345,inode号为6789)。然后,您可以将其移至所需的/Users/jdoe/someFile.txt
任何位置(相同的音量),并且一切正常。您甚至可以编写支持此功能的Shell脚本magic
。
ls -di <file>
获取索引节点号。
$ ls -di /User/jdoe/someFile.txt
6789 /User/jdoe/someFile.txt
编辑:
您可以stat
根据IMSoP突出显示的链接答案来获取卷的ID和索引节点号。
GetFileInfo /.vol/12345/6789
将返回先前位于中的文件的当前位置/Users/jdoe/someFile.txt
。
有关更多信息,请参见/programming/11951328/is-there-any-function-to-retrieve-the-path-associated-with-an-inode。
/.vol/
并且仍然会发生(尽管我需要pwd -P
,只有这样,plain的输出pwd
才会更新)。我猜程序不必通过任何特殊的路径打开文件,因为通常它们会获取(并保留)内核始终映射到inode的文件描述符。我怀疑在Mac /.vol/
上也不是必不可少的。
bash
在Debian上做到了。我运行exec 3<>foo
,然后foo
在同一文件系统中移动echo whatever >&3
,然后foo
在新位置签入-并进行了更改。尽管bash
无法在文件中查找,但其他程序通常可以。我的观点/.vol/
不是必须的,没有它,程序可以很容易地像这样工作。或者我不明白有什么区别。
以下答案是错误的(请参阅评论)。请无视
除了thecarpy给出的良好答案之外,您的程序可能还只是持有一个文件句柄,而该文件句柄与目录树中的文件位置无关(并且在Unix系统上,甚至持续删除文件,至少直到您将其关闭为止) )。
文件句柄基本上是对文件的直接访问,而与文件在目录结构中的位置或存在频率(在硬链接的情况下)无关。
尽管我不确定macos为什么使用此功能而不是标准C功能,但假设我几年前在“ Mac OS X Unleashed”中阅读的内容是正确的,事实证明我又学到了一些新知识。
请看下面的简单C程序:
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
struct timespec ts;
ts.tv_sec = 10;
ts.tv_nsec = 0;
FILE * fp;
fp = fopen("file.txt", "a");
int f = fileno(fp);
if (fp == NULL)
{
printf("Error opening file!\n");
exit(1);
}
struct stat file_stat;
int ret;
ret = fstat (f, &file_stat);
printf("inode number is %d\n", file_stat.st_ino);
nanosleep(&ts, NULL);
printf("Finished sleep, writing to file.\n");
/* print some text */
const char *text = "Write this to the file";
dprintf(f, "Some text: %s\n", text);
/* print integers and floats */
int i = 1;
float py = 3.1415927;
dprintf(f, "Integer: %d, float: %f\n", i, py);
/* printing single characters */
char c = 'A';
dprintf(f, "A character: %c\n", c);
close(f);
}
编译该程序,在后台运行,mv file.txt file2.txt
然后在程序打印“完成睡眠,写入文件”之前快速运行它。(您有10秒)
请注意,file2.txt
尽管在文本打印到文件之前已移动程序(通过文件描述符),但它具有程序的输出。
$ gcc myfile.c
$ ./a.out &
[1] 21416
$ inode number is 83956
$ ./mv file.txt file2.txt
$ Finished sleep, writing to file.
[1]+ Done ./a.out
$ cat file2.txt
Some text: Write this to the file
Integer: 1, float: 3.141593
A character: A
免责声明:我还没有删掉“包含”列表,所以很快就被黑了,以证明这一点。
stat
这里的命令比更为有用ls -di
,因为它告诉您卷/设备ID以及文件ID /索引节点号。