文件描述符和文件指针有什么区别?

发布于 2024-08-25 02:46:42 字数 33 浏览 3 评论 0原文

文件描述符和文件指针有何关系?什么时候适合分别使用?

How are file descriptors and file pointers related? When is it appropriate to use each?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

蓝色星空 2024-09-01 02:46:43

文件描述符是一个低级整数“句柄”,用于在 Linux 和其他类 Unix 系统中识别内核级别打开的文件(或套接字或其他任何内容)。

您将“裸”文件描述符传递给实际的 Unix 调用,例如 read()write() 等等。

FILE 指针是 C 标准库级构造,用于表示文件。 FILE 包装文件描述符,并添加缓冲和其他功能以使 I/O 更容易。

您将 FILE 指针传递给标准 C 函数,例如 fread()fwrite()

A file descriptor is a low-level integer "handle" used to identify an opened file (or socket, or whatever) at the kernel level, in Linux and other Unix-like systems.

You pass "naked" file descriptors to actual Unix calls, such as read(), write() and so on.

A FILE pointer is a C standard library-level construct, used to represent a file. The FILE wraps the file descriptor, and adds buffering and other features to make I/O easier.

You pass FILE pointers to standard C functions such as fread() and fwrite().

初吻给了烟 2024-09-01 02:46:43

一个是缓冲的 (FILE *),另一个不是。实际上,当您从“真实”文件(即驱动器上)读取时,您几乎总是希望使用 FILE * ,除非您知道自己在做什么,或者除非您的文件实际上是一个 从

您可以使用 fileno()FILE * 获取文件描述符,并且可以 使用 fdopen() 的文件描述符

One is buffered (FILE *) and the other is not. In practice, you want to use FILE * almost always when you are reading from a 'real' file (ie. on the drive), unless you know what you are doing or unless your file is actually a socket or so..

You can get the file descriptor from the FILE * using fileno() and you can open a buffered FILE * from a file descriptor using fdopen()

寂寞陪衬 2024-09-01 02:46:43

文件描述符只是一个从 POSIX open() 调用中获得的整数。使用标准 C fopen() 你会得到一个 FILE 结构体。 FILE 结构包含此文件描述符以及其他内容,例如文件结束和错误指示符、流位置等。

因此,使用 fopen() 可以为您提供一定量的与 open() 相比的抽象。一般来说,您应该使用 fopen() 因为它更便携,并且您可以使用使用 FILE 结构的所有其他标准 C 函数,即 fprintf () 和家人。

使用两者都不存在性能问题。

A file descriptor is just an integer which you get from the POSIX open() call. Using the standard C fopen() you get a FILE struct back. The FILE struct contains this file descriptor amongst other things such as end-of-file and error indicator, stream position etc.

So using fopen() gives you a certain amount of abstraction compared to open(). In general you should be using fopen() since that is more portable and you can use all the other standard C functions that uses the FILE struct, i.e., fprintf() and family.

There are no performance issues using either.

尹雨沫 2024-09-01 02:46:43

文件描述符与文件指针

文件描述符:

文件描述符是由open()系统调用返回的整数值。

int fd = open (filePath, mode);

  1. 低/内核级别处理程序。
  2. 传递给 UNIX 系统调用的 read() 和 write()。
  3. 不包括缓冲等功能。
  4. 便携性较差且缺乏效率。

文件指针:

文件指针是指向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;
  1. 它是高级接口。
  2. 传递给 fread() 和 fwrite() 函数。
  3. 包括缓冲、错误指示、EOF检测等。
  4. 提供更高的便携性和效率。

File descriptor vs File pointer

File descriptor:

File Descriptor is an integer value returned by open() system call.

int fd = open (filePath, mode);

  1. Low/Kernel level handler.
  2. passe to read() and write() of UNIX System Calls.
  3. Doesn't include buffering and such features.
  4. Less portable and lacks efficiency.

File pointer:

File Pointer is a pointer to a C structure returned by fopen() library function, which is used to identifying a file, wrapping the file descriptor, buffering functionality and all other functionality needed for I/O operation.The file pointer is of type FILE, whose definition can be found in "/usr/include/stdio.h". This definition may vary from one compiler to another.

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;
  1. It is high level interface.
  2. Passed to fread() and fwrite() functions.
  3. Includes buffering,error indication and EOF detection,etc.
  4. Provides higher portability and efficiency.
各空 2024-09-01 02:46:43

想添加可能有用的点。

ABOUT FILE *

  1. 不能用于进程间通信(IPC)。
  2. 当您需要通用缓冲 I/O 时使用它。(printf,frpintf,snprintf,scanf)
  3. 我多次使用它来记录调试日志。
    例如,

    <前><代码> 文件 *fp;
    fp = fopen("debug.txt","a");
    fprintf(fp,"我已经达到了这一点");
    fclose(fp);

ABOUT FILE DESCRIPTOR

  1. 一般用于IPC。

  2. 控制。(设备、文件、套接字等),因此比 FILE * 更强大。

Want to add points which might be useful.

ABOUT FILE *

  1. can't be used for interprocess communication(IPC).
  2. use it when you need genral purpose buffered I/O.(printf,frpintf,snprintf,scanf)
  3. I use it many times for debug logs.
    example,

                 FILE *fp;
                 fp = fopen("debug.txt","a");
                 fprintf(fp,"I have reached till this point");
                 fclose(fp);
    

ABOUT FILE DESCRIPTOR

  1. It's generally used for IPC.

  2. Gives low-level control to files on *nix systems.(devices,files,sockets,etc), hence more powerfull than the FILE *.

能否归途做我良人 2024-09-01 02:46:43

当您处理文本文件和用户输入/输出时,FILE * 更有用,因为它允许您使用 sprintf()sscanf() 等 API 函数fgets()feof() 等。

文件描述符 API 是低级的,因此它允许使用套接字、管道、内存映射文件(当然还有常规文件)。

FILE * is more useful when you work with text files and user input/output, because it allows you to use API functions like sprintf(), sscanf(), fgets(), feof() etc.

File descriptor API is low-level, so it allows to work with sockets, pipes, memory-mapped files (and regular files, of course).

我要还你自由 2024-09-01 02:46:43

只是结束讨论的注释(如果有兴趣)......

fopen 可能不安全,您应该使用 fopen_sopen具有专属位设置。 C1X 提供 x 模式,因此您可以使用 "rx""wx" 等模式 fopen

如果您使用 open,您可能会考虑 open(..., O_EXCL | O_RDONLY,... )open(..., O_CREAT | O_EXCL | O_WRONLY,...)

例如,请参阅不要对 fopen() 和文件创建做出假设

Just a note to finish out the discussion (if interested)....

fopen can be insecure, and you should probably use fopen_s or open with exclusive bits set. C1X is offering x modes, so you can fopen with modes "rx", "wx", etc.

If you use open, you might consider open(..., O_EXCL | O_RDONLY,... ) or open(..., O_CREAT | O_EXCL | O_WRONLY,... ).

See, for example, Do not make assumptions about fopen() and file creation.

风和你 2024-09-01 02:46:43

我在这里找到了一个很好的资源 ,高度概括了两者之间的差异:

当您想要对文件进行输入或输出时,您可以选择两种基本机制来表示程序和文件之间的连接:文件描述符和流。文件描述符表示为 int 类型的对象,而流表示为 FILE * 对象。

文件描述符为输入和输出操作提供了一个原始的低级接口。文件描述符和流都可以表示与设备(例如终端)的连接,或者用于与另一个进程通信的管道或套接字,以及普通文件。但是,如果您想要执行特定于特定类型设备的控制操作,则必须使用文件描述符;没有以这种方式使用流的设施。如果您的程序需要以特殊模式(例如非阻塞(或轮询)输入)进行输入或输出,您还必须使用文件描述符(请参阅文件状态标志)。

流提供了一个更高级别的接口,位于原始文件描述符设施之上。流接口对所有类型的文件的处理方式非常相似,唯一的例外是您可以选择的三种缓冲样式(请参阅流缓冲)。

使用流接口的主要优点是,用于在流上执行实际输入和输出操作(而不是控制操作)的函数集比文件描述符的相应设施更丰富、更强大。文件描述符接口只提供了简单的字符块传输功能,但流接口还提供了强大的格式化输入输出函数(printf和scanf)以及面向字符和行的输入和输出函数。

由于流是根据文件描述符实现的,因此您可以从流中提取文件描述符并直接对文件描述符执行低级操作。您还可以首先打开一个连接作为文件描述符,然后创建一个与该文件描述符关联的流。

一般来说,您应该坚持使用流而不是文件描述符,除非您想要执行的某些特定操作只能在文件描述符上完成。如果您是一名初级程序员并且不确定要使用哪些函数,我们建议您重点关注格式化输入函数(请参阅格式化输入)和格式化输出函数(请参阅格式化输出)。

如果您担心程序向 GNU 以外的系统的可移植性,您还应该意识到文件描述符不像流那样可移植。您可以期望任何运行 ISO C 的系统都支持流,但非 GNU 系统可能根本不支持文件描述符,或者可能只实现对文件描述符进行操作的 GNU 函数的子集。然而,GNU C 库中的大多数文件描述符函数都包含在 POSIX.1 标准中。

I found a good resource here, giving high level overview of differences between the two:

When you want to do input or output to a file, you have a choice of two basic mechanisms for representing the connection between your program and the file: file descriptors and streams. File descriptors are represented as objects of type int, while streams are represented as FILE * objects.

File descriptors provide a primitive, low-level interface to input and output operations. Both file descriptors and streams can represent a connection to a device (such as a terminal), or a pipe or socket for communicating with another process, as well as a normal file. But, if you want to do control operations that are specific to a particular kind of device, you must use a file descriptor; there are no facilities to use streams in this way. You must also use file descriptors if your program needs to do input or output in special modes, such as nonblocking (or polled) input (see File Status Flags).

Streams provide a higher-level interface, layered on top of the primitive file descriptor facilities. The stream interface treats all kinds of files pretty much alike—the sole exception being the three styles of buffering that you can choose (see Stream Buffering).

The main advantage of using the stream interface is that the set of functions for performing actual input and output operations (as opposed to control operations) on streams is much richer and more powerful than the corresponding facilities for file descriptors. The file descriptor interface provides only simple functions for transferring blocks of characters, but the stream interface also provides powerful formatted input and output functions (printf and scanf) as well as functions for character- and line-oriented input and output.

Since streams are implemented in terms of file descriptors, you can extract the file descriptor from a stream and perform low-level operations directly on the file descriptor. You can also initially open a connection as a file descriptor and then make a stream associated with that file descriptor.

In general, you should stick with using streams rather than file descriptors, unless there is some specific operation you want to do that can only be done on a file descriptor. If you are a beginning programmer and aren’t sure what functions to use, we suggest that you concentrate on the formatted input functions (see Formatted Input) and formatted output functions (see Formatted Output).

If you are concerned about portability of your programs to systems other than GNU, you should also be aware that file descriptors are not as portable as streams. You can expect any system running ISO C to support streams, but non-GNU systems may not support file descriptors at all, or may only implement a subset of the GNU functions that operate on file descriptors. Most of the file descriptor functions in the GNU C Library are included in the POSIX.1 standard, however.

违心° 2024-09-01 02:46:43

系统调用主要使用文件描述符,例如readwrite。库函数将使用文件指针(printfscanf)。但是,库函数仅使用内部系统调用。

System calls are mostly using file descriptor, for example read and write. Library function will use the file pointers ( printf , scanf). But, library functions are using internally system calls only.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文