文件描述符 和 流的关系

本文详细解析了UNIX系统中用于表示程序与文件连接的两种机制——文件描述符与流,包括它们的相同点、不同点以及相互关系。重点讨论了在特定设备控制操作和非阻塞I/O操作方面文件描述符的优势,同时阐述了流提供的高级I/O接口及其在程序移植性方面的优点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

任何一种操作系统中,程序在开始读写一个文件的内容之前,必须首先在程序与文件之间建立连接或通信通道,这一过程称为打开文件。打开一个文件的目的可以是为了读或者为了写,也可以是即读又写。
    UNIX系统中有两种机制用于描述程序与文件的这种连接:
    (1)文件描述符

    (2)流

文件描述符 和 流:相同点:

1. 都是用来表示用户程序与被操作的文件之间的连接,并在此连接的 基础上对文件进行读写等访问。

2. 都能表示与普通文件,与设备(如终端),与管道或者套接字的连接,用户打开一个文件,要么返回文件描述符,要么返回一个流。

3.  都包含了一大类的I/O库函数

文件描述符 和 流:不同点:

文件描述符表示为int类型的对象。例如标准输入对应文件描述符0,标准输出对应文件描述符1。
而流则表示为指向结构FILE的指针FILE* ,因此流也称为“文件指针”

如果需要对特定设备进行控制操作,必须使用文件描述符方式,没有函数能对流进行这类操作。

如果需要按照特殊的方式进行I/O操作(例如非阻塞的方式),必须使用文件描述符方式,也没有函数能对流进行这类操作。

文件描述符 和 流的关系:

     流给用户程序提供了更高一级的(功能更强大,使用更简化)的I/O接口,它处在文件描述符方式的上层,也就是说,流函数是通过文件描述符函数来实现的。

流 相对于 文件描述符 的 优点:

执行实际输入输出操作的流函数集合比文件描述符函数要丰富很多,而功能也灵活,强大不少。 

文件描述符函数只提供简单的传送字符块的函数

流函数提供格式化I/O,字符I/O,面向行的I/O等大量函数

流函数有利于程序的移植,任何基于ANSI C的系统都支持流,文件描述符的支持则较弱

转自http://blog.csdn.net/yuanzhangmei1/article/details/9131971

### 文件描述符与文件指针的区别与联系 #### 一、基本概念 文件描述符(File Descriptor, FD)是一个非负整数,由操作系统分配给每个打开的文件或设备。它是进程文件描述符表中的索引,用于标识当前进程中已打开的文件资源[^2]。 文件指针(`FILE *`)则是 C/C++ 编程语言中的一种数据结构,通常用于高级 I/O 操作。它封装了底层的文件描述符以及其他元信息(如缓冲区状态),提供了更友好的接口供开发者使用[^5]。 --- #### 二、主要区别 1. **层次不同** - 文件描述符属于操作系统层面的概念,直接对应于内核维护的文件对象。 - 文件指针则位于应用层,是对文件描述符的一次封装,便于程序员进行更高层次的操作[^4]。 2. **功能范围** - 文件描述符仅支持低级操作,例如 `read()`、`write()`、`close()` 等系统调用。 - 文件指针除了能够完成类似的读写操作外,还额外支持格式化输入输出(如 `fprintf()`、`fscanf()`)、错误处理机制以及自动缓冲管理等功能[^5]。 3. **实现方式** - 文件描述符本质上只是一个整数值,在 Linux 或其他类 Unix 系统下代表某个特定的文件或者网络连接等资源。 - 而 FILE 结构体内部包含了指向实际文件描述符的字段(比如 `_fileno` 成员变量)。这意味着可以通过访问该成员获取到关联的基础文件描述符[^5]。 4. **跨平台特性** - 使用文件描述符编写程序具有良好的可移植性,因为几乎所有现代操作系统都遵循 POSIX 标准实现了统一 API 集合。 - 对应地,尽管标准库定义了一致的行为模式,但由于具体实现细节可能有所差异,因此基于文件开发的应用可能会遇到兼容性问题[^3]。 --- #### 三、两者之间的关系 虽然它们分属不同的抽象级别,但在某些情况下可以互相转换: - 在 C 库函数的帮助下,可以从现有的文件创建一个新的独立副本并获得相应的新文件描述符;反之亦然——利用 fdopen 函数可以把原始裸露出来的数字型句柄重新包装成易于使用的 stream object 形式[^5]。 下面展示一段简单的例子说明如何在这两种形式之间切换: ```c #include <stdio.h> #include <unistd.h> int main() { int fd = fileno(stdin); // 获取 stdin 的文件描述符 printf("Standard Input File Descriptor: %d\n", fd); FILE* fp = fdopen(1, "w"); // 将 stdout (file descriptor '1') 转换回 file pointer fprintf(fp, "This is written via a FILE pointer.\n"); fclose(fp); return 0; } ``` 此代码片段先是从预设的标准输入提取出它的基础编号表示法即文件描述符,接着又演示怎样把另一个方向上的标准化输出端口映射回去形成新的高级别 IO 接口实例。 --- ### 总结 综上所述,文件描述符文件指针各有优劣之处:前者更加贴近硬件本质且效率较高但灵活性较差;后者虽牺牲了一些性能却极大地简化了复杂场景下的编码工作量并且增强了安全性保障措施。根据项目需求合理选用合适的工具才是最重要的原则之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值