Can someone explain to me precisely the difference between a file descriptor and a file handle (separate from Windows' definition for the term; I'm curious about their definition, but that would require a much longer answer)?
From what I have gathered from Wikipedia, a file descriptor is an index in a file descriptor table, which points to a file name in a file table, which in turn points to an inode in an inode table. File handle is a type of data structure that stores a file descriptor.
At least one file descriptor exists for every open file on the system. File descriptors were first used in Unix, and are used by modern operating systems including Linux, macOS, and BSD. In Microsoft Windows, file descriptors are known as file handles.
What is the File Descriptor? File descriptor is integer that uniquely identifies an open file of the process. File Descriptor table: File descriptor table is the collection of integer array indices that are file descriptors in which elements are pointers to file table entries.
Nothing: there are three standard file descriptions, STDIN, STDOUT, and STDERR. They are assigned to 0, 1, and 2 respectively.
First of all we need separate interface and implementation.
On POSIX conforming systems, you get int
as result of open(2)
and
after that you can use this int
for writing, reading and so on operations.
This is interface.
In the kernel, which manage open files for concrete process, map from int
to some structure that kernel used to manage files may be implemented in many
ways, may be array, may be binary tree and so on.
As for linux kernel, for each open file it has struct file
,
and to work with int
kernel has to map int
to address of struct file
.
It do it in such simple way - fdt->fd[fd]
, where ftd
is pointer to struct fdtable
, fd
is file descriptor (int
) (I do not describe the way of how kernel handle multi thread access to tables). This is current implementation in Linux kernel. It can be changed in the future.
File handle that return CreateFile
is used in similar to file descriptor way,
it is integer, that used as index to access Windows analog of struct file
in per process table.
So I think that file handle and file descriptor may be used as synonyms,
but usually when talk about file handle
mean HANDLE, and when talk about
file descriptors talk about POSIX int
return by open
. On windows
HANDLE
also used to manage events, GUI windows and so on,
this is not true for file descriptors
on POSIX systems, but
on POSIX systems file descriptors
also used to manage sockets,
while on windows this was impossible until winsock 2.
And about FILE.
FILE in interface above file descriptor
and file handle
,
it has one of them inside, plus some data to manage buffered I/O.
For example from popular linux C runtime glibc:
struct _IO_FILE {
int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags
/* The following pointers correspond to the C++ streambuf protocol. */
/* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
char* _IO_read_ptr; /* Current read pointer */
char* _IO_read_end; /* End of get area. */
char* _IO_read_base; /* Start of putback+get area. */
char* _IO_write_base; /* Start of put area. */
char* _IO_write_ptr; /* Current put pointer. */
char* _IO_write_end; /* End of put area. */
char* _IO_buf_base; /* Start of reserve area. */
char* _IO_buf_end; /* End of reserve area. */
/* The following fields are used to support backing up and undo. */
char *_IO_save_base; /* Pointer to start of non-current get area. */
char *_IO_backup_base; /* Pointer to first valid character of backup area */
char *_IO_save_end; /* Pointer to end of non-current get area. */
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
//...
};
As you can see it has _fileno
, it file descriptor
which glibc
get from OS by open(2)
call. But it has a lot of stuff to buffering, translate end of lines etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With