文件描述符可能的取值是什么?

21

我希望了解文件描述符可以期望的有效值。

请允许我解释一下。我知道,在我的Linux系统上使用#include <unistd.h>时,调用打开文件进行读取:

int fileDescriptor;
fileDescriptor = open("/some/filename",O_RDONLY);

可能会发生错误并且我会收到-1作为结果。
顺便提一下,(-1)负一必须有某种特殊含义。这是因为所有其他值都是有效的文件描述符吗?即也包括像-2和-1023这样的负数?

假设int为4个字节(sizeof(int)==4),那么会怎样呢?

(-1) = 10000000 0000000 00000000 00000001

仅会是唯一可检测到的无效文件描述符吗?其他的可能是:

  • (0) = 00000000 0000000 00000000 00000000
  • (-2) = 10000000 0000000 00000000 00000010
  • (2) = 00000000 0000000 00000000 00000010

可以吗? 因为文件描述符可以存储4个字节,所以我最多有(2^(8*4)-1)个有效文件描述符,因此这将是我可以打开的文件的最大数量,对吗?

再说得简单点:

我应该期望一个(有效的)文件描述符是什么样子?

除了-1之外任何值都行吗?


文件描述符,是一个小的、非负整数,用于后续系统调用。请参阅 man 2 open。 - Sakthi Kumar
请参考这个问题,了解可以在Linux中打开的文件/文件描述符的最大数量。 - jotik
5个回答

23

来自man页:

open()返回一个文件描述符,一个小的、非负的整数

然后:

open()creat()返回新的文件描述符,如果发生错误则返回-1


1
我建议澄清“小”是指小于RLIMIT_NOFILE(如果这总是这种情况)。 - Praxeolitic
在Linux中,零(0)是否是一个有效的文件描述符? - Gabriel Staples
1
在Linux系统的汇编中: 0是标准输入(stdin), 1是标准输出(stdout), 2是标准错误(stderr)。 - Ximaz

3
open失败时,它将返回-10xffffffff,这没有任何意义,只说明open执行失败。

成功完成操作后,该函数将打开文件并返回表示最低编号未使用的文件描述符的非负整数。否则,将返回-1,并设置errno以指示错误。如果函数返回-1,则不会创建或修改任何文件。

失败的原因存储在errno中,您可以读取其值并检查是否为可能的失败原因之一:EACCESEEXISTEINTR等,或者使用perror打印错误消息。

2

Linux系统(32位或64位系统)的文件描述符可能值的范围是从0到1023。

您不能创建值大于1023的文件描述符。如果使用值为1024的文件描述符,则会返回一个EBADF错误(坏的文件描述符,错误编号-9)。

当返回文件描述符的负值时,表示发生了错误。


9
注意,1024只是RLIMIT_NOFILE(ulimit -n)的惯常默认值。 如果您增加它,它将支持每个进程超过1024个文件。(另外一个相关的限制是系统范围的文件描述符限制,与单个进程无关 - 这由fs.file-max sysctl设置控制) - Simon Kissane

1

以下是Linux 手册页的内容:

open()creat()返回新文件描述符,如果发生错误则返回-1(此时会适当设置errno)。

其他系统在出现错误时可能会返回其他负值。


1

文件描述符基本上是系统在运行程序时跟踪所有打开文件(和一些其他类型的I/O通道)的方法。它们表示为整数,您可以将它们视为程序用于处理文件的一种“ID”或“句柄”。

让我们考虑一个现实生活的类比。想象一下你是一名图书管理员,每当有人借一本书时,你都会给他们一张带有独特编号的票。稍后,当他们想归还书或询问有关书籍时,他们向您展示票据,您可以立即知道他们所说的是哪本书。在这个比喻中,文件描述符就是票上的数字。

当您在程序中打开文件时,操作系统会给您分配一个文件描述符——最小未使用的数字——以便您将来引用该文件。当您从该文件读取或写入时,使用该文件描述符。当您完成文件操作时,您“关闭”它,这告诉系统您已经完成了该文件描述符,它可以将该数字用于其他用途。

文件描述符的确切限制取决于您的系统,但通常相当高(数千甚至数万)。每个打开的文件、管道或其他资源会消耗一个文件描述符。

以下是一些标准文件描述符值:

0:标准输入(stdin)

1:标准输出(stdout)

2:标准错误(stderr)

这些是每个进程中可用的默认文件描述符。当您使用open函数打开文件时,您会得到一个文件描述符,它始终是当前未为该进程打开的最低编号文件描述符。对于第一个打开的文件,通常为3,第二个为4,以此类推。

文件描述符保持打开状态,直到显式关闭它或进程终止。重要的是,在完成文件描述符操作后始终关闭它们,以防止文件描述符泄漏,这可能导致进程耗尽可用于其的文件描述符数量。

示例:

write(1, "a", 1); //First argument represent the Standard Output.
write(4, "a", 1); //4 is not currently open or valid, then the write function will fail, and it will return -1 to indicate an error. 


int fd;

fd = open("42", O_RDWR | O_CREAT | O_APPEND, 0777); //Create file "42"
printf("%d\n", fd); // => fd value is 3 because it takes the next smallest int available (0, 1 and 2) are always taken.

fd 可以根据您的系统达到数千个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接