2015-11-05 80 views
2

有人可以向我解釋一個文件描述符和文件句柄之間的區別嗎(與Windows的術語定義不同;我對它們的定義很好奇,但這需要一個更長的答案)?文件描述符和文件句柄(和C)

從我從維基百科收集的信息來看,文件描述符是文件描述符表中的一個索引,它指向文件表中的文件名,該文件名又指向inode表中的inode。文件句柄是一種存儲文件描述符的數據結構。

  • 文件描述符只是文件描述符表 中的一個索引(即索引值只是文件描述符)?
  • 或者由它的索引標識的文件描述符表元素是否存儲文件描述符(使它們可能是兩個不同的數字,假設索引是數字)?
  • 「文件句柄」只是C語言中存儲文件描述符的FILE數據結構的術語嗎?或者文件句柄引用了一些其他的數據結構,它存儲了與C數據結構(FILE)分開的文件描述符?還有誰能告訴我關於文件句柄數據結構的性質?
+0

在C通常我們講的描述符和流:http://www.gnu.org/software/libc/manual/html_node/Descriptors-and- Streams.html#描述符和數據流 –

+0

查看描述符和數據流--http://www.gnu.org/software/libc/manual/html_node/Streams-and-File-Descriptors.html – ameyCU

回答

1

首先我們需要單獨的接口和實現。 在符合POSIX標準的系統上,您可以獲得int作爲open(2)和 的結果,然後您可以使用此int進行寫入,讀取等操作。 這是接口。

在內核中,其管理打開文件的具體過程,從int 到內核用於管理文件的一些結構圖可以以多種 方式來實現,也可以返回數組,可能是二叉樹等。

至於Linux內核,每個打開的文件,它有struct file, 與int內核工作映射int解決struct file。 它以這種簡單的方式執行 - fdt->fd[fd],其中ftd是指向struct fdtable的指針,fd是文件描述符(int)(我沒有描述內核如何處理多線程訪問表的方式)。這是Linux內核當前的實現。它可以在將來改變。

文件句柄返回CreateFile在類似於用於文件描述符的方式, 它是整數,即作爲索引來訪問的struct file的Windows模擬在每個進程表。

所以我認爲,文件句柄和文件描述符可以作爲同義詞, 但通常當談及file handle指處理,而當談 文件描述符談論POSIX int回報的open。在Windows HANDLE還可以用來管理事件,GUI窗口等, 這不是file descriptors在POSIX系統,但 真正的POSIX系統file descriptors還可以用來管理插座, 而上,這是不可能的窗口,直到Winsock 2的。

關於FILE。 接口上面的文件file descriptorfile handle, 它有一個裏面,加上一些數據來管理緩衝的I/O。 例如從流行的Linux C運行時的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; 
//... 
}; 

正如你可以看到它有_fileno,它file descriptorglibc通過open(2)調用從OS獲得。但它有很多東西來緩衝,翻譯行尾等。