如果我执行以下操作:
touch /tmp/test
然后执行
ls -la /tmp/
我可以看到该test
文件0 字节在目录中。
但是操作系统如何处理这个概念0 字节。如果我用通俗的话来说:
0 字节根本没有内存,因此什么也没有创建。
创建文件,必须或者应该至少需要一定的记忆力吧?
答案1
文件(大致)是三个独立的东西:
- “inode”,一种元数据结构,用于跟踪文件的所有者、权限以及磁盘上实际包含数据的块列表。
- 指向该 inode 的一个或多个目录条目(文件名)
- 实际的数据块本身
创建空文件时,仅创建索引节点和指向该索引节点的目录条目。稀疏文件也同样 ( dd if=/dev/null of=sparse_file bs=10M seek=1
)。
当您创建到现有文件的硬链接时,您只需创建指向同一 inode 的其他目录条目。
我在这里简化了事情,但你明白了。
答案2
touch
将创建一个索引节点、 和ls -i
或stat
将显示有关 inode 的信息:
$ touch test
$ ls -i test
28971114 test
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fc01h/64513d Inode: 28971114 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/1000) Gid: ( 1000/1000)
Access: 2017-03-28 17:38:07.221131925 +0200
Modify: 2017-03-28 17:38:07.221131925 +0200
Change: 2017-03-28 17:38:07.221131925 +0200
Birth: -
请注意,test
使用 0 个块。为了存储显示的数据,索引节点使用一些字节。这些字节存储在索引节点表中。查看 ext2 页面以获取inode 结构示例。
答案3
ls
(或者好吧,stat(2)
系统调用)告诉你的大小内容文件的。文件系统需要多少空间来记账不是其中的一部分,并且作为实现细节,它不是一般编程的内容应该关心甚至知道。使实现细节可见将使文件系统抽象变得不那么有用。
答案4
简单的答案:因为它是这样定义的。
更长的答案:这样定义是因为某些操作在概念上更简单:
- 如果一个文件包含 20 个字母“A”,并且您删除所有“A”,则该文件将缩短 20 个字节。对仅包含“AAAAAAAAAAAAAAAAAAA”的文件执行相同的操作必须处理消失文件的特殊情况。
- 更实际的是,删除文本文件的最后一行需要特殊处理。
- 定期进行备份的文本编辑器需要特殊情况的代码来处理用户可能删除最后一行,去吃午饭,然后回来添加另一行的情况。如果其他用户同时创建了具有该名称的文件,则会出现进一步的复杂情况。
您可以做更多的事情: * 错误日志文件往往被创建为空,当且仅当发生错误时才会被填充。 * 要了解发生了多少错误,请计算日志文件中的行数。如果日志文件为空,则错误数为零,这是完全有道理的。 * 有时您会看到文件名中包含所有相关文本的文件,例如this-is-the-logging-directory
.这可以防止过于急切的管理员在安装后删除空目录,并且还可以防止程序或用户意外创建程序想要稍后查看目录的文件的错误。程序git
(和其他程序)倾向于忽略空目录,如果项目/管理员/用户想要记录该目录存在,即使它没有有用的内容(尚未),您可能会看到一个名为empty
或 的空文件empty.directory
。
没有操作变得更复杂:
- 连接文件:这只是一个空文件的无操作。
- 在文件中搜索字符串:“如果文件短于搜索项,则它不能包含搜索项”的标准情况涵盖了这一点。
- 从文件中读取:程序需要在获得预期内容之前处理到达文件末尾的情况,因此零长度文件的情况并不需要程序员进行额外的思考:他只会到达文件末尾- 从头开始文件。
就文件而言,“在某处记录了一个文件”方面(inode 和/或文件名)位于上述考虑因素之上,但如果空文件无用,文件系统将不会这样做。
一般来说,除了与文件名相关的原因外,上述所有原因都适用于序列。最值得注意的是字符串,它是字符序列:零长度字符串在程序中很常见。如果字符串没有意义,则通常在用户级别不允许使用:文件名是字符串,大多数文件系统不允许空字符串作为文件名;在内部,当从片段创建文件名时,程序很可能将空字符串作为片段之一。