要使文件成为 POSIX 定义的文本文件,必须满足哪些条件?

Har*_*her 28 posix files text

POSIX 将文本文件定义为:

包含组织成零个或多个行的字符的文件。这些行不包含 NUL 字符,并且长度不能超过 {LINE_MAX} 个字节,包括 <newline> 字符。尽管 POSIX.1-2017 不区分文本文件和二进制文件(参见 ISO C 标准),但许多实用程序仅在对文本文件进行操作时产生可预测或有意义的输出。具有此类限制的标准实用程序总是在其 STDIN 或 INPUT FILES 部分中指定“文本文件”。

来源:http : //pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_403

但是,有几件事我觉得不清楚:

  1. 文本文件必须是普通文件吗?在上面的摘录中没有明确说明文件必须是常规文件

  2. 如果文件只包含一个字符和一个字符(即不以换行符结尾的单个字符),是否可以将文件视为文本文件?我知道这个问题可能听起来很挑剔,但他们使用“字符”一词而不是“一个或多个字符”。其他人可能不同意,但如果他们的意思是“一个或多个字符”,我认为他们应该明确地说出来

  3. 在上面的摘录中,它提到了“线条”。我发现了四个名称中带有 line 的定义:“Empty Line”、“Display Line”、“Incomplete Line”和“Line”。我是否应该推断它们的意思是“线”,因为它们省略了“空”、“显示”和“不完整”——或者所有这四个定义都被认为是上面摘录中的一条线?

此文本块之后出现的所有问题都取决于推断“字符”表示“一个或多个字符”:

  1. 我可以安全地推断,如果一个文件是空的,它就不是一个文本文件,因为它不包含一个或多个字符吗?

此文本块之后的所有问题都取决于推断,在上面的摘录中,一行被定义为“行”,并且应排除名称中包含“行”的其他三个定义:

  1. “零行或多行”中的“零”是否意味着如果文件包含一个或多个未以换行符终止的字符,则仍可将其视为文本文件?

  2. “零行或多行”是否意味着一旦单个“行”(0 个或多个字符加上终止换行符)开始发挥作用,最后一行成为“不完整行”(一个或多个非文件末尾的换行符)?

  3. “无 [无行] 的长度可以超过 {LINE_MAX} 个字节,包括换行符”是否意味着文本文件中任何给定“行”中允许的字符数有限制(顺便说一句, Ubuntu 18.04 和 FreeBSD 11.1 上的 LINE_MAX 是“2048”)?

Mic*_*mer 29

  1. 文本文件必须是普通文件吗?在上面的摘录中没有明确说明文件必须是常规文件

    不; 摘录甚至特别指出标准输入作为潜在的文本文件。其他标准实用程序,例如 make专门字符特殊文件 /dev/null 用作文本文件

  2. 如果文件只包含一个字符和一个字符(即不以换行符结尾的单个字符),是否可以将文件视为文本文件?

    该字符必须是 <newline>,或者这不是line,因此它所在的文件不是文本文件。恰好包含字节 0A 的文件是单行文本文件。空行是有效行。

  3. 在上面的摘录中,它提到了“线条”。我发现了四个名称中带有 line 的定义:“Empty Line”、“Display Line”、“Incomplete Line”和“Line”。我是否应该推断它们的意思是“线”,因为它们省略了“空”、“显示”和“不完整”

    这不是真正的推理,只是它所说的。“线”这个词已经给出了一个适合上下文的定义,所以这就是它所谈论的。

  4. 我可以安全地推断,如果一个文件是空的,它就不是一个文本文件,因为它不包含一个或多个字符吗?

    一个空文件由零(或更多)行组成,因此是一个文本文件。

  5. “零行或多行”中的“零”是否意味着如果文件包含一个或多个未以换行符终止的字符,则仍可将其视为文本文件?

    不,这些字符没有组织成行。

  6. “零行或多行”是否意味着一旦单个“行”(0 个或多个字符加上终止换行符)开始发挥作用,最后一行成为“不完整行”(一个或多个非文件末尾的换行符)?

    这不是非法的,它只是不是一个文本文件。如果改为提供文本文件,则需要为其提供文本文件的实用程序可能会产生不利的行为。

  7. “无[无行] 的长度可以超过 {LINE_MAX} 个字节,包括换行符”是否意味着文本文件中任何给定“行”中允许的字符数有限制

    是的。

这个定义只是试图对基于文本的实用程序(例如,grep)肯定会接受的内容设置一些界限——仅此而已。他们也可以更自由地接受事物,而且在实践中经常这样做。他们被允许使用固定大小的缓冲区来处理一行,假设换行符在它满之前出现,等等。你可能读得太多了。

  • @terdon:我看不出迈克尔的回答有任何矛盾。基本上,他似乎是在说 POSIX 文本文件是内容与正则表达式 `(.{0,M}\n)*`(隐式锚定和两端)匹配的任何文件,其中 `\n` 匹配换行符和`.` 匹配任何不是换行符的字符,而 `M` 是数值 LINE_MAX-1 的占位符。特别是,这意味着空文件是由零行组成的有效文本文件,但任何非空文本文件都必须以换行符结尾(否则它将包含不完整的行,不完整的行不是行)。 (7认同)

ImH*_*ere 7

根据 POSIX 的定义:

是的,文本文件(基本上)是:

包含组织成零个或多个行的字符的文件。

还包括以下定义会很有用:

3.92 字符串

由第一个空字节终止并包括第一个空字节的连续字符序列。

3.195 不完整的线

文件末尾的一个或多个非 <newline> 字符的序列。

3.206线

零个或多个非 <newline> 字符加上终止 <newline> 字符的序列。

3.243 换行符 (<newline>)

输出流中的一个字符表示打印应该从下一行的开头开始。它是C语言中'\n'指定的字符。未指定该字符是否是系统传输到输出设备以完成移动到下一行的确切序列。

3.247 空

所有位都设置为零的字符。

请注意,“文本文件”将包含NUL字节。


所以:

  1. 文本文件必须是普通文件吗?
    不,它不需要。“文本文件”是根据读取时包含的内容来定义的。如果文件包含“零行或多行”,则它是一个文本文件。某些文件(如/dev/stdin)可能包含一个文本文件,如果一次读取而不是在下一次读取时。
  2. 如果一个文件只包含一个字符和一个字符,是否可以将其视为文本文件……?
    不,那是一条不完整的线 (3.195)。
    文本文件应只有非“不完整行”。
  3. 我应该推断他们的意思是“线”......?
    是的你应该。
  4. 我可以安全地推断出,如果一个文件是空的,它就不是一个文本文件……?
    不,空文件(零个字符)是有效的“文本文件”。
    从上面:...零个或多个行......。零行(零字符)是有效的“文本文件”。
  5. ...如果包含一个或多个不以换行符终止的字符,则视为文本文件?
    不,“不完整的行”(技术上)不是有效的“行”。
  6. “零行或多行”中的“零”是否意味着如果文件包含一个或多个不以换行符结尾的字符,它仍然可以被视为文本文件?
    不,不完整的线不是“线”。一个文本文件,将不会有不完整的线。

  7. ……文本文件中任何给定“行”中允许的字符数有限制……?
    是的,在有效“文本文件”的任何给定行中,不得超过 {LINE_MAX}个字节(与字符相反)。
    {LINE_MAX} 的值在文件 <limits.h> 中给出
    (也读取C 中的 Sensible line buffer size?):

    {LINE_MAX}
    除非另有说明,当实用程序被描述为处理文本文件时,实用程序的输入行(标准输入或另一个文件)的最大长度(以字节为单位)。长度包括尾随的空间。
    最小可接受值:{_POSIX2_LINE_MAX}

    对于基于 GNU 的系统,没有设置限制(内存除外)

    宏:int LINE_MAX
    面向文本的 POSIX.2 实用程序可以支持的最大文本行。(如果您使用这些实用程序的 GNU 版本,那么除了可用虚拟内存强加的限制之外,没有实际限制,但库无法告诉您这一点。)

    它似乎被定义 posix_lim.h为 2048(至少对于 64 位 linux GNU 系统):

    $ grep -ri 'POSIX2_LINE_MAX' /usr/include/ 
    
    /usr/include/x86_64-linux-gnu/bits/xopen_lim.h:#define NL_LANGMAX       _POSIX2_LINE_MAX
    /usr/include/x86_64-linux-gnu/bits/posix2_lim.h:#define _POSIX2_LINE_MAX                2048
    /usr/include/x86_64-linux-gnu/bits/posix2_lim.h:#define LINE_MAX                _POSIX2_LINE_MAX
    
    Run Code Online (Sandbox Code Playgroud)

    也可以使用 POSIX实用程序 getconf找到它:

    $ getconf LINE_MAX
    2048
    
    Run Code Online (Sandbox Code Playgroud)

相关: 为什么文本文件应该以换行符结尾?

  • 这个答案大部分是正确的,但“文本文件必须是常规文件”的正确答案是*否*。任何类型的文件都可以是文本文件,这是内容问题,文件类型无关紧要。`file` 实用程序只报告特殊文件的文件类型,但这就是该实用程序的工作方式,使用 `file - &lt;...` 或 (Linux) `file -s ...` 来查看它对特殊文件内容的启发式文件。每次打开一个特殊文件时,它的内容可能不同,因此每次打开时它可能是文本文件,也可能是文本文件。`/dev/null` 总是一个文本文件,因为它的内容总是一个文本文件。 (2认同)