には保存されません そのファイル。これはファイルシステムに保存され、すべてのパラメーターは手動で 1 つずつコピーされます (ただし、まったくコピーできないものもあります)。
つまり、ほとんどのオペレーティング システムには、実際には「メタデータを含むファイルのコピー」呼び出しがありません。ファイル コピー プログラムは、foobar.py
という名前の新しいファイルを作成するだけです。 、データの 0 バイト全体をコピーし、utime() または SetFileTime() を使用して、変更時刻を元の時刻と同じにします。同様に、ファイル許可は、chmod() を使用して新たに設定するか、POSIX ACL 属性をコピーすることによって「コピー」されます。
一部のメタデータはコピーされません。所有権の設定には root 権限が必要です。そのため、他のユーザーのファイルのコピーはあなたに属し、あなたの を占有します。 ディスク クォータ。 ctime (属性変更時刻) は Unix では手動で設定できません。通常、btime (誕生/作成時刻) もコピーされません。
cp -a foo bar
を比較 (メタデータをコピーする) と cp foo bar
(そうではありません):
$ strace -v cp foo bar … open("foo", O_RDONLY) = 3 open("bar", O_WRONLY|O_TRUNC) = 4 read(3, "test\n", 131072) = 5 write(4, "test\n", 5) = 5 read(3, "", 131072) = 0 close(4) = 0 close(3) = 0 …
$ strace -v cp -a foo bar … -- original metadata is retrieved lstat("foo", {st_dev=makedev(254, 0), st_ino=60569468, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=5, st_atime=2016-12-28T09:16:59+0200.879714332, st_mtime=2016-12-28T09:16:55+0200.816363098, st_ctime=2016-12-28T09:16:55+0200.816363098}) = 0 -- data is copied open("foo", O_RDONLY|O_NOFOLLOW) = 3 open("bar", O_WRONLY|O_TRUNC) = 4 read(3, "test\n", 131072) = 5 write(4, "test\n", 5) = 5 read(3, "", 131072) = 0 -- modifiction time is copied utimensat(4, NULL, [{tv_sec=1482909419, tv_nsec=879714332}, {tv_sec=1482909415, tv_nsec=816363098}], 0) = 0 -- ownership is copied (only with 'sudo [strace] cp') fchown(4, 1000, 1000) = 0 -- extended attributes are copied (xdg.origin.url is set by browsers, wget) flistxattr(3, NULL, 0) = 0 flistxattr(3, "user.xdg.origin.url\0", 20) = 20 fgetxattr(3, "user.xdg.origin.url", "https://superuser.com/", 22) = 22 fsetxattr(4, "user.xdg.origin.url", "https://superuser.com/", 22, 0) = 0 -- POSIX ACLs are not present, so a basic ACL is built from st_mode -- (in this case, a simple fchmod() would work as well) fgetxattr(3, "system.posix_acl_access", 0x7ffc87a50be0, 132) = -1 ENODATA (No data available) fsetxattr(4, "system.posix_acl_access", "\2\0\0\0\1\0\6\0\377\377\377\377\4\0\4\0\377\377\377\377 \0\4\0\377\377\377\377", 28, 0) = 0 close(4) = 0 close(3) = 0 …
通常、メタデータが保存されているファイルシステムごとに異なります。ファイルシステムのext2ファミリーでは、言及したメタデータ(所有者、グループ、権限、時間)はinodeに保存されます。 inode には、ファイルがディスク上で占有するブロックも格納 (ポインター) されます。 inode はしない ファイル名を保存します。
stat
でこのデータにアクセスできます システムコール (man 2 stat
)、stat
を使用します。 それを印刷するためのツール (man stat
)。 inode フィールドの詳細な説明は、linux/include/linux/fs.h
にあります。 カーネルソースで。
別の場所に保存されている他の種類のメタデータ (ACL アクセス許可など) があります。
ファイルをコピーするとき、既定ではメタデータはコピーされません。代わりに、デフォルトのメタデータ値を持つ新しいファイルが作成されます。 cp
にはさまざまなオプションがあります (-p
、 --preserve
) cp
を指示する stat
で古いメタデータを読み取ることにより、メタデータもコピーします それに応じて新しいメタデータを変更します。
ファイル システムに応じて、権限、サイズなどのメタデータ (場合によってはファイル名も) を保持するために、領域が (半) 静的または動的に予約されます。
Unix では、メタデータは inode に保存されます ファイルが存在するデータ領域を制御します (ファイル名と関連する i ノード番号はディレクトリ エントリに格納されます)。
一部のファイルシステムでは、ディレクトリエントリは他のファイルと同様にファイルですが、ビューから隠されています。 FAT と FAT32 はそのようなファイルシステムです (ただし、FAT のルート ディレクトリは「特殊」です)。ファイルを作成するときは、ファイルが存在するフォルダを説明するエントリをファイルに追加/編集します。各エントリは、ファイル サイズ、名前、日付などを格納するのに十分な大きさです (長い名前は複数のエントリを占有します。デフォルトのエントリ サイズである 32 バイトは、古い 8+3 文字形式で 1 つの名前を保持できます。もちろん、これらすべては、 、私の記憶が働いていると仮定して)。 Ext システムも同様ですが、ディレクトリ エントリは動的にサイズ変更され、名前と inode ポインタのみを保持します。他のすべての情報は inode にあります。このようにして、2 つのエントリが同じファイルを指すことができるため、重複ファイルの管理に役立ちます。
一部のファイルシステムでは、メタデータに加えて少量のデータを保持するのに十分な大きさの inode があり、ファイルがそこに収まる場合は余分なディスク領域を占有しません。 45 バイトのファイルを作成しても、ディスクの空き容量はまったく変化しません。これらのバイトは 内部 に保存されます iノード。 ext* ファミリーはこれをサポートしていると思います (そして NTFS も)。これは、多数の非常に小さなファイルを管理するのに役立ちます。
さらに他のファイル システムでは、これらの追加の属性を格納する、メインのファイル システムに沿った「ファントム」ファイル システムに相当するものがあります。ファイル情報だけでなく、おそらくファイル アイコンも同様です。
一部のシステムには両方があります。NTFS には、inode のような方法で動作する完全なディレクトリ メタデータがあり、代替データ ストリームを作成する可能性があります。 「メイン」ファイル内の (明らかに) 何も変更しない追加情報を保持します。