与任何外设无关的流的 C 语法

C syntax of a stream not associated to any peripheral

我在下面引用《The C Programming Language》第二版。

B.1 输入和输出:,第 2 节:

A stream is a source or destinaton of data that may be associated with a disk or other peripheral.

然后可以说流可能不会与任何外围设备相关联:流可以存在而不与任何外围设备相关联外设.

因此出现以下问题:不与任何外围设备关联的流看起来像什么?

考虑到作者

B.1 输入和输出:,第 3 节:

[...] use "file pointer" and "stream" interchangeably [...]

FILE *p;
p = NULL;

这么好的答案?

这取决于你如何定义'peripheral'。有些特殊设备不是 "peripherals" 意义上的连接到机器的硬件。

例如,/dev/null/dev/zero 就是两个这样的设备。如果你打开它们(/dev/zero 用于读取,/dev/null 用于读取或写入),然后将流与其相关联,它们并不是真正与外围设备通信。您也可以对 /dev/random and/or /dev/urandom 提出同样的论点(它们是只读的)。

在 Linux 上,您可以打开 /proc 文件系统下的文件 — 它们不直接与外围设备关联。

如果"file pointer"和"stream"确实被用作严格的同义词,那么:

FILE *fp = NULL;

定义了一个 stream 没有(还)与任何外围设备相关联。也不是 (还)与数据的任何来源或目的地相关联。

如果你要问布赖恩·克尼汉或已故的丹尼斯·里奇,"Is fp really a steam there?", 他们可能会说“好吧,也许不是。每当它 正在使用 用于 I/O 时,它就是一个流 - 当你成功打开它时,直到你 成功关闭。不用的时候说是流,还是文件指针,都没什么大不了的。"

用于 I/O 的文件指针(或流)是一些 C 中的编程表示 数据的来源或目的地。该源或目标可能是 - 或者在 - 外围设备上 例如 U 盘、SSD 或 HDD、磁带卷或终端。或者它可能不会。 C的定义 不指定或限制 a FILE * 可以表示 的数据源或目标的物理实现。这就是为什么书中说数据的来源或目的地可能与磁盘或其他外围设备相关联。

C 标准库仅提供函数 fopen, in <stdio,h>(及其强化变体 fopen_s)作为 一种从头开始创建流的方法。1 它提供了众所周知的现成 FILE *stdinstdoutstderr<stdio.h> 提供的流通常但不一定与外围设备相关联。

标准库以外的 C 库可能会为您提供函数 返回与外围设备无关的 FILE * 流。例如。这 Linux C 库为您 fmemopen 和朋友提供, 提供 FILE * I/O 到 内存区域 .

您甚至可以仅使用 <stdio.h> 工具在内存中读取或写入 FILE * 流。 Linux 允许您轻松创建 tmpfs 虚拟内存 文件系统。然后,您可以完全用标准 C 编写程序来执行常规 FILE * I/O 在您的 tmpfs 文件系统中,其中 none 将与外围设备相关联。 C 不知道也不关心文件系统的实现。


[1] 还有 freopenfreopen_s,它们关闭现有流并打开 再次使用新文件名。