Answers:
文件描述符是一个低级整数“句柄”,用于在Linux和其他类似Unix的系统中在内核级别标识打开的文件(或套接字,或其他)。
您将“裸”文件描述符传递给实际的Unix调用,例如read()
,write()
等等。
甲FILE
指针是一个C标准库级构建体,用于表示一个文件。该FILE
包装的文件描述符,并增加了缓冲等功能,使I / O更容易。
fd
是的第一个参数read()
。你为什么称它为裸体?
FILE *
类型相比,整数文件描述符是“较少包装”的,即“裸”的。
文件描述符与文件指针
文件描述符:
文件描述符是open()
系统调用返回的整数值。
int fd = open (filePath, mode);
文件指针:
文件指针是指向fopen()
库函数返回的C结构的指针,该函数用于标识文件,包装文件描述符,缓冲功能以及I / O操作所需的所有其他功能。文件指针的类型为FILE,其定义可以在“ /usr/include/stdio.h”中找到。此定义可能因一个编译器而异。
FILE *fp = fopen (filePath, mode);
// A FILE Structure returned by fopen
typedef struct
{
unsigned char *_ptr;
int _cnt;
unsigned char *_base;
unsigned char *_bufendp;
short _flag;
short _file;
int __stdioid;
char *__newbase;
#ifdef _THREAD_SAFE
void *_lock;
#else
long _unused[1];
#endif
#ifdef __64BIT__
long _unused1[4];
#endif /* __64BIT__ */
} FILE;
要添加可能有用的点。
关于 FILE *
我将它多次用于调试日志。例,
FILE *fp;
fp = fopen("debug.txt","a");
fprintf(fp,"I have reached till this point");
fclose(fp);
关于 FILE DESCRIPTOR
通常用于IPC。
对* nix系统上的文件(设备,文件,套接字等)进行低级控制,因此比.x更强大FILE *
。
fdopen()
IPC和设备做诸如此类的事情FILE*
吗?
FILE*
,但可以FILE*
从文件描述符(fdopen()
)创建一个,然后关闭FILE
也会关闭该描述符。因此,您可以执行 IPC,但是您必须稍微处理文件描述符以促进任何直接IPC。
FILE *
更有用,当你用文本文件和用户输入/输出工作,因为它允许你使用API功能,如sprintf()
,sscanf()
,fgets()
,feof()
等。
文件描述符API是低级的,因此它允许使用套接字,管道,内存映射文件(当然还有常规文件)。
只要注意一下,即可结束讨论(如果有兴趣的话)...
fopen
可能是不安全的,您可能应该使用fopen_s
或open
设置了独占位。C1X是提供x
模式,这样你就可以fopen
与模式"rx"
,"wx"
等等。
如果使用open
,则可以考虑open(..., O_EXCL | O_RDONLY,... )
或open(..., O_CREAT | O_EXCL | O_WRONLY,... )
。
例如,请参见不要假设fopen()和文件创建。
fopen_s
似乎没有办法POSIX
,我认为最轻便的灵魂就是到open(2)
那时fdopen(2)
。(将窗户放在一边)。此外,会更快fopen_s()
或更open(2)
紧随其后的是fdopen(2)
什么?
系统调用主要使用文件描述符,例如read
和 write
。库函数将使用文件指针(printf
,scanf
)。但是,库函数仅在内部使用系统调用。
我在这里找到了很好的资源,对两者之间的差异进行了高层次的概述:
当您要输入或输出到文件时,可以选择两种基本机制来表示程序与文件之间的连接:文件描述符和流。文件描述符表示为int类型的对象,而流表示为FILE *对象。
文件描述符为输入和输出操作提供了原始的低级接口。文件描述符和流都可以表示与设备(例如终端)的连接,或者用于与另一个进程进行通信的管道或套接字以及普通文件的连接。但是,如果要执行特定于特定类型设备的控制操作,则必须使用文件描述符;没有以这种方式使用流的设施。如果程序需要在特殊模式下(例如非阻塞(或轮询)输入)进行输入或输出,则还必须使用文件描述符(请参见文件状态标志)。
流提供了一个更高层的接口,位于原始文件描述符工具之上。流接口对所有类型的文件都非常相似-唯一的例外是可以选择的三种缓冲样式(请参见流缓冲)。
使用流接口的主要优点是,与用于文件描述符的相应功能相比,用于在流上执行实际输入和输出操作(与控制操作相对)的功能集要丰富得多,功能也要强大得多。文件描述符接口仅提供用于传输字符块的简单功能,而流接口还提供了功能强大的格式化输入和输出功能(printf和scanf)以及面向字符和行的输入和输出功能。
由于流是根据文件描述符实现的,因此您可以从流中提取文件描述符,然后直接对文件描述符执行低级操作。您还可以首先打开一个连接作为文件描述符,然后创建与该文件描述符关联的流。
通常,除非要执行某些只能在文件描述符上执行的特定操作,否则应坚持使用流而不是文件描述符。如果您是新手程序员,并且不确定要使用哪些函数,建议您专注于格式化输入函数(请参阅格式化输入)和格式化输出函数(请参见格式化输出)。
如果您担心程序到GNU以外的系统的可移植性,则还应该注意文件描述符不像流那样可移植。您可以期望任何运行ISO C的系统都支持流,但是非GNU系统可能根本不支持文件描述符,或者只能实现对文件描述符进行操作的GNU函数的子集。但是,GNU C库中的大多数文件描述符函数都包含在POSIX.1标准中。