文件描述符和文件指针有什么关系?何时适合使用每个?
文件描述符和文件指针有什么关系?何时适合使用每个?
FILE *
类型相比,整数文件描述符更少包装,即更为“裸露”。 - unwind其中一个是带缓存的(FILE *
),另一个则不带。实际上,当您从“真实”文件(即在驱动器上)中读取时,几乎总是希望使用 FILE *
,除非您知道自己在做什么或者文件实际上是一个套接字等。
您可以使用 fileno()
从 FILE *
获取文件描述符,并且可以使用 fdopen()
打开一个带缓冲的 FILE *
。
文件描述符只是从POSIX的open()
调用中获取的整数。使用标准C的fopen()
可获得FILE
结构体返回。除文件描述符外,FILE
结构体还包含其他信息,例如文件结束和错误指示器、流位置等。
因此,与open()
相比,使用fopen()
提供了一定程度的抽象。通常情况下,应该使用fopen()
,因为它更具移植性,可以使用所有其他使用FILE
结构体的标准C函数,例如fprintf()
及其系列函数。
使用任何一个都没有性能问题。
文件描述符 vs 文件指针
文件描述符:
文件描述符是由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);
关于文件描述符
它通常用于进程间通信。
在*nix系统中,它对文件(设备、文件、套接字等)提供低级别的控制,因此比 FILE *
更强大。
fdopen()
来处理 IPC 和设备,使用 FILE*
吗? - osveinFILE*
来设置和初始化IPC,但是你可以通过文件描述符(fdopen()
)创建一个FILE*
,并且稍后关闭FILE
也会关闭描述符。因此,你可以做IPC,但是你必须处理一些文件描述符以便于任何直接的IPC。 - Micah WFILE *
在处理文本文件和用户输入/输出时更加实用,因为它允许您使用API函数,如sprintf()
、sscanf()
、fgets()
、feof()
等。
文件描述符API是低级的,因此它允许处理套接字、管道、内存映射文件(当然也包括常规文件)。
这里简要说明一下(如果您感兴趣)...
fopen
可能存在安全问题,建议使用 fopen_s
或带有 exclusive bits 的 open
。C1X 提供了 x
模式,可以使用 "rx"
、"wx"
等模式来打开文件。
如果使用 open
,可以考虑使用 open(..., O_EXCL | O_RDONLY,... )
或 open(..., O_CREAT | O_EXCL | O_WRONLY,... )
。
例如,请参见《不要对 fopen() 和文件创建进行假设》。
fopen_s
,因此假设最可移植的解决方案是使用open(2)
和fdopen(2)
(不考虑Windows)。另外,哪个更快,fopen_s()
还是使用open(2)
和fdopen(2)
? - Mihir Luthra系统调用主要使用文件描述符,例如read
和write
。库函数将使用文件指针(printf
,scanf
)。但是,库函数仅在内部使用系统调用。