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
不过,我觉得有几点不清楚:
文本文件必须是常规文件吗?在上面的摘录中,它没有明确说明该文件必须是常规文件
如果一个文件只包含一个字符且仅包含一个字符(即不以换行符结尾的单个字符),是否可以将其视为文本文件?我知道这个问题可能听起来很挑剔,但他们使用“字符”一词而不是“一个或多个字符”。其他人可能不同意,但如果他们的意思是“一个或多个字符”,我认为他们应该明确地说出来
在上面的摘录中,它提到了“线”。我发现了四个名称中带有行的定义:“空行”、“显示行”、“不完整行”和“行”。我是否应该推断它们的意思是“线”,因为它们省略了“空”、“显示”和“不完整”——或者所有这四个定义都被视为上面摘录中的一条线?
该文本块之后出现的所有问题都取决于推断“字符”意味着“一个或多个字符”:
- 我是否可以安全地推断,如果文件为空,则它不是文本文件,因为它不包含一个或多个字符?
该文本块之后出现的所有问题都取决于推断,在上面的摘录中,一条线被定义为“Line”,并且名称中包含“Line”的其他三个定义应被排除:
“零或更多行”中的“零”是否意味着如果一个文件包含一个或多个不以换行符结尾的字符,则该文件仍然可以被视为文本文件?
“零或更多行”是否意味着一旦单个“行”(0个或多个字符加上终止换行符)开始发挥作用,最后一行成为“不完整行”(一个或多个非完整行)就变得非法文件末尾的换行符)?
“none [no line] 的长度不能超过 {LINE_MAX} 个字节,包括换行符”是否意味着文本文件中任何给定“行”中允许的字符数存在限制(顺便说一句, Ubuntu 18.04 和 FreeBSD 11.1 上的 LINE_MAX 是“2048”)?
答案1
文本文件必须是常规文件吗?在上面的摘录中,它没有明确说明该文件必须是常规文件
不;摘录甚至特别指出标准输入作为潜在的文本文件。其他标准实用程序,例如
make
,具体使用这字符特殊文件/dev/null
作为文本文件。如果一个文件只包含一个字符且仅包含一个字符(即不以换行符结尾的单个字符),是否可以将其视为文本文件?
该字符必须是 <newline>,否则不是一条线,因此它所在的文件不是文本文件。恰好包含字节 0A 的文件是单行文本文件。空行是有效行。
在上面的摘录中,它提到了“线”。我发现了四个名称中带有行的定义:“空行”、“显示行”、“不完整行”和“行”。我是否应该推断它们的意思是“线”,因为它们省略了“空”,“显示”和“不完整”
这并不是真正的推论,只是它所说的。这个单词“线”已被赋予上下文适当的定义这就是它所讨论的内容。
我是否可以安全地推断,如果文件为空,则它不是文本文件,因为它不包含一个或多个字符?
空文件由零(或更多)行组成,因此是一个文本文件。
“零或更多行”中的“零”是否意味着如果一个文件包含一个或多个不以换行符结尾的字符,则该文件仍然可以被视为文本文件?
不,这些字符没有组织成行。
“零或更多行”是否意味着一旦单个“行”(0个或多个字符加上终止换行符)开始发挥作用,最后一行成为“不完整行”(一个或多个非完整行)就变得非法文件末尾的换行符)?
它不是非法的,它只是不是一个文本文件。需要提供文本文件的实用程序可能如果给定该文件,则会出现不良行为。
“none [no line] 的长度不能超过 {LINE_MAX} 个字节,包括换行符”是否意味着文本文件中任何给定“行”中允许的字符数有限制
是的。
这个定义只是试图对基于文本的实用程序设置一些界限(例如,grep
)肯定会接受——仅此而已。他们也可以更自由地接受事物,而且在实践中他们经常这样做。他们被允许使用固定大小的缓冲区来处理一行,假设换行符在其满之前出现,等等。你可能对事物解读太多了。
答案2
根据 POSIX 的定义:
是的,文本文件(基本上)是:
包含组织成零行或多行的字符的文件。
包含以下定义也会很有用:
以第一个空字节结尾并包含第一个空字节的连续字符序列。
文件末尾的一个或多个非 <newline> 字符的序列。
零个或多个非 <newline> 字符加上终止 <newline> 字符的序列。
输出流中的字符指示打印应从下一行的开头开始。是C语言中'\n'指定的字符。未指定该字符是否是系统传输到输出设备以完成到下一行的移动的确切序列。
所有位都设置为零的字符。
请注意,“文本文件”应不是包含 NUL 字节。
所以:
- 文本文件必须是常规文件吗?
不,不需要。 “文本文件”是根据读取时包含的内容来定义的。如果文件包含“零行或多行”,则它是文本文件。某些文件(例如/dev/stdin
)如果一次读取但在下一次读取时可能不包含文本文件。 - 如果一个文件包含一个字符并且仅包含一个字符......,是否可以将其视为文本文件?
不,这是一条不完整的线 (3.195)。
文本文件应仅包含非“不完整行”。 - 我是否应该推断它们的意思是“线”……?
是的你应该。 - 我可以安全地推断,如果文件为空,则它不是文本文件......?
不,空文件(零字符)是有效的“文本文件”。
从上面:…零行或多行…。零行(零字符)是有效的“文本文件”。 - …如果包含一个或多个不以换行符结尾的字符,则视为文本文件?
不,“不完整的线”不是(技术上)有效的“线”。 “零或更多行”中的“零”是否意味着如果一个文件包含一个或多个不以换行符结尾的字符,则该文件仍然可以被视为文本文件?
不,不完整的线不是“线”。文本文件应不是有不完整的线条。...文本文件中任何给定“行”中允许的字符数有限制...?
是的,不超过 {LINE_MAX}字节(与字符相对)应允许出现在有效“文本文件”的任何给定行中。
{LINE_MAX} 的值由以下公式给出文件<limits.h>
(另请阅读C 中合理的行缓冲区大小?):{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
也可以使用 POSIX 找到它实用程序 getconf:
$ getconf LINE_MAX 2048
有关的: 为什么文本文件应该以换行符结尾?