在 Linux 中创建零字节文件的概念是什么?

Sha*_*sai 31 linux filesystems files

如果我执行以下操作:

touch /tmp/test
Run Code Online (Sandbox Code Playgroud)

然后执行

ls -la /tmp/
Run Code Online (Sandbox Code Playgroud)

我能看到的test文件,0字节的目录。

但是操作系统如何处理0 Bytes的概念。如果我用外行的话来说:

0 字节根本就不是内存,因此没有创建任何内容。

创建一个文件,必须或至少应该需要一定的内存,对吗?

xhi*_*nne 65

一个文件(大致)是三个独立的东西:

  • “inode”,一种元数据结构,用于跟踪谁拥有文件、权限以及磁盘上实际包含数据的块列表。
  • 一个或多个指向该 inode 的目录条目(文件名)
  • 实际的数据块本身

当您创建一个空文件时,您只创建了 inode 和一个指向该 inode 的目录条目。稀疏文件 ( dd if=/dev/null of=sparse_file bs=10M seek=1) 也是如此。

当您创建到现有文件的硬链接时,您只需创建指向同一 inode 的附加目录条目。

我在这里简化了事情,但你明白了。

  • 应该是*三个*单独的东西:包含数据的块列表;*块本身*;以及指向块列表的目录条目(或条目)。 (6认同)
  • @Theophrastus 好点。我已经使简化事情成为可能。实际上,在块列表和目录条目之间,存在与文件有关的元数据(由 inode 编号表示)并包含文件属性(所有者、权限等)和扩展属性。块列表在那里。所以所有的目录条目并不直接指向块列表(FAT 方式),而是指向元数据。 (4认同)
  • 很好地说明。通过您的“硬链接”段落提出一个小难题:如果创建一个指向空文件的硬链接,而您声明该文件没有块列表,那么该硬链接如何指向(相同)块列表哪个不存在? (2认同)

ctx*_*ctx 24

touch将创建一个inode,并且ls -istat将显示有关 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: -
Run Code Online (Sandbox Code Playgroud)

请注意,test使用 0 块。为了存储显示的数据,inode 使用了一些字节。这些字节存储在 inode 表中。查看 ext2 页面以获取inode 结构示例


ilk*_*chu 19

ls(或者好吧,stat(2)系统调用)告诉您文件内容的大小。文件系统需要多少空间进行簿记不是其中的一部分,作为一个实现细节,它不是一般程序应该关心甚至知道的东西。使实现细节可见会使文件系统抽象变得不那么有用。


Pat*_*her 8

文件本身不占用任何空间,但文件系统会占用任何空间,存储文件名、位置、访问权限等。

  • 如果您查看目录条目占用的空间,如果您有一个包含一千个大小为 0 字节的文件的目录,该目录将比只有 2 个大文件的目录条目大。 (4认同)
  • 提及文件是一个抽象概念,与其在磁盘上的物理表示没有紧密联系的道具。 (2认同)

too*_*ger 5

简单的回答:因为它是这样定义的。

更长的答案:这样定义是因为某些操作在概念上更简单:

  • 如果文件包含 20 个字母“A”,并且您删除所有“A”,则文件将缩短 20 个字节。对仅包含“AAAAAAAAAAAAAAAAAAAAA”的文件执行相同的操作必须处理文件消失的特殊情况。
  • 更实际地,删除文本文件的最后一行需要特殊情况。
  • 定期进行备份的文本编辑器需要特殊情况代码来处理用户可能删除最后一行、去吃午饭然后回来添加另一行的情况。如果其他一些用户同时创建了具有该名称的文件,则会出现进一步的复杂情况。

你可以做更多的事情: * 错误日志文件往往被创建为空,当且仅当发生错误时才填充。* 要找出发生了多少错误,您可以计算日志文件中的行数。如果日志文件为空,则错误数为零,这是完全合理的。* 有时您会看到所有相关文本都在文件名中的文件,例如this-is-the-logging-directory. 这可以防止过于急切的管理员在安装后删除空目录,还可以防止程序或用户不小心创建了程序稍后希望看到目录的文件的错误。该git程序(和其他程序)倾向于忽略空目录,如果项目/管理员/用户想要记录该目录存在的记录,即使它没有有用的内容(还),您可能会看到一个名为的空文件emptyempty.directory

没有操作变得更复杂:

  • 连接文件:这只是一个空文件的空操作。
  • 在文件中搜索字符串:这包含在“如果文件比搜索词短,则不能包含搜索词”的标准情况下。
  • 从文件中读取:程序需要在获得预期内容之前处理到达文件末尾的问题,因此零长度文件的情况再次不需要程序员额外考虑:他只会点击文件末尾-文件从头开始。

在文件的情况下,“有一个文件记录在某处”方面(inode 和/或文件名)位于上述考虑之上,但如果空文件无用,文件系统将不会这样做。

一般来说,除与文件名有关的原因外,上述所有原因都适用于序列。最值得注意的是字符串,它是字符序列:零长度字符串在程序中很常见。如果字符串没有意义,通常在用户级别是不允许的:文件名是字符串,大多数文件系统不允许空字符串作为文件名;在内部,从片段创建文件名时,程序很可能将空字符串作为片段之一。