回答:
macosには/.vol/
、実際のディレクトリとファイルにマップされる特別なシステムがあります。ファイルがディレクトリにあるか/.vol/<device_id>/<inode_number>
どうかに関係なく、ファイルとディレクトリはを介してアクセスできます。
素敵な小さなシステムです。
したがって、プログラムは、たとえば、iノード番号を取得し/Users/jdoe/someFile.txt
てから開くことができます/.vol/12345/6789
(この場合、デバイスIDは12345、iノード番号は6789です)。次に、/Users/jdoe/someFile.txt
好きな場所(同じボリューム上)に移動すると、すべてが機能します。これをサポートするシェルスクリプトを作成することもできmagic
ます。
ls -di <file>
iノード番号を取得します。
$ ls -di /User/jdoe/someFile.txt
6789 /User/jdoe/someFile.txt
編集:
あなたが使う stat
IMSoPで強調表示されているリンクされた回答に従って、ボリュームのIDとiノード番号を取得します。
GetFileInfo /.vol/12345/6789
は、以前ににあったファイルの現在の場所を返します/Users/jdoe/someFile.txt
。
詳細については、https://stackoverflow.com/questions/11951328/is-there-any-function-to-retrieve-the-path-associated-with-an-inodeを参照してください。
/.vol/
、これはまだ起こります(必要なのにpwd -P
、plainの出力pwd
が更新されるだけです)。プログラムは特別なパスを介してファイルを開く必要がないと思います。一般に、それらはカーネルによってiノードにマップされるファイル記述子を取得(および保持)するためです。私は疑う 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
免責事項:「include」リストを整理していませんが、これはポイントを証明するためにすぐにハッキングされました。
stat
するためls -di
、ここよりも便利なコマンドです。