Macアプリはファイルの場所をどのように追跡しますか?

Macアプリはファイルの場所をどのように追跡しますか?

Macでは、次の動作を観察しました。

  • PDF Expertを使用してPDFを開き、ファイルをいくつか変更し、Finderでファイルを移動し、PDF Expertに保存すると、新しい場所に正しく保存されます。
  • 同様のディレクトリでシェルを開き、~/foo別のアプリケーションにディレクトリをごみ箱に入れると、シェルのpwdが正しく出力されます~/.Trash/foo

後ろで何が起こるのか?このような状況は、アプリケーションがemacsのようにファイルへの絶対パスを保存しないことを示しているようです(私は正しいですか?)それともまったく異なるメカニズムですか?

答え1

macosには、/.vol/物理​​ディレクトリとファイルにマッピングされる特別なシステムがあります。/.vol/<device_id>/<inode_number>ファイルとディレクトリは、ファイルシステムの場所に関係なくアクセスできます。

良い小さなシステムです。

したがって、プログラムはinode番号を取得して/Users/jdoe/someFile.txtから/.vol/12345/6789開くことができます(この場合、デバイスIDは12345、inode番号は6789です)。その後、/Users/jdoe/someFile.txt好きな場所(同じボリューム)に移動でき、すべてがうまく機能します。この機能をサポートするシェルスクリプトを作成することもできますmagic

ls -di <file>インデックスノード番号を取得します。

$ ls -di /User/jdoe/someFile.txt
6789 /User/jdoe/someFile.txt

編集する:

statIMSoP強調表示されたリンク回答から、ボリュームのIDとinode番号を取得できます。

GetFileInfo /.vol/12345/6789以前にあったファイルの現在位置を返します/Users/jdoe/someFile.txt

バラよりhttps://stackoverflow.com/questions/11951328/is-there-any-function-to-retrieve-the-path-linked-with-an-inodeより多くの情報を知りたいです。

答え2

以下の回答は間違っています(コメントを参照)。無視してください


thecarpyが提供した良い答えに加えて、あなたのプログラムはファイルを保存する可能性があります。扱う、これはディレクトリツリー内のファイルの場所とは無関係です(そして、Unixシステムでは、少なくともファイルを閉じるまでファイルの削除は続行されます)。

ファイルハンドルは、デフォルトでは、ディレクトリ構造内のファイルの場所や頻度(ハードリンクの場合)に関係なく、ファイルへの直接アクセスです。

答え3

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

免責事項:「含む」リストを整理しておらず、これを証明するためにすばやく整理しました。

関連情報