open V.S. fopen
# 關鍵字 :
open, read, write、fopen, fread, fwrite、file descriptor(fd)、information node(inode)、File Pointer
# 如何解決 : (問題解釋 & 步驟)
# open, read, write : 檔案 I/O
。prototype :
open() 系統呼叫
```
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *name, int flags);
int open(const char *name, int flags, mode_t mode);
```
#include <unistd.h> // read(), write(), close()
ssize_t read(int fd, void *buf, size_t len);
ssize_t write(int fd, const void *buf, size_t count);
int close(int fd);
```
。POSIX 定義,system call,只能用在 POSIX 的作業系統,使用"fopen"會較容易移植。
。檔案必須被開啟才可以被存取。你可以透過一個獨一無二的描述器(descriptor)來參用一個已開啟的檔案。在「Linux kernel」內部,此描述器是透過一個「file descriptor,fd (檔案描述符器)」的整數(C的int資料型別)來進行操作。(p11)
。fd由「用戶空間」程式所共享,「用戶空間」程式可以直接使用fd來存取檔案。「Linux 系統程式」多半是以fd來進行檔案的開啟、操作、關閉以及其他工作。
。用戶空間和核心空間都會把「fd(file descripor)」當成獨一無二的「每行程識別符(per-process cookie)」:開啟一個檔案便會回傳一個「fd」,而隨後的操作(read, write,etc)則會以「fd」作為主要的引數,
。「資訊節點 (information node,inode)」(p12) :
- 盡管檔案的存取通常是經由檔案名稱(file name),但檔案通常和名稱沒直接關聯性。檔案的參用是透過「資訊節點 (information node,inode)」,inode會被
賦予一個獨一無二的整數值,此值被稱為「資訊節點編號 (inode number,i-number,ino)」。
- inode用來儲存與某個檔案有關的中介資料,例如檔案的時間戳記、擁有者、類型、長度以及檔案資料的擺放位置,就是沒有檔名。
- inode是一個實際的物件,也是一個概念性實體(由Linux kernel裡的一個資料結構表示)。
。I/O級別相對低層,更接近作業系統,讀寫時「沒有緩衝」。
。sample code :
https://github.com/walter-cc/Linux_Device_Driver/commit/224480a9f68cbebd2a7cf5c9c94acd0fdae890c3
# fopen, fread, fwrite : 標準 I/O
。prototype :
```
#include <stdio.h> // standard I/O
FILE *fopen(const char *path, const char *mode);
int fclose(FILE *stream);
size_t fread(void *buf, size_t size, size_t nr, FILE *stream);
size_t fwrite(void *buf, size_t size, size_t nr, FILE *stream);
```
。標準的C庫函式,較具有可移植性。
。「檔案指標(File Pointer,File handler)」(p76) : FILE *fopen()
標準I/O常式不會直接操作fd,而會使用他們自己的識別符(identifier),稱為檔案指標(File Pointer)。
。必須對正規檔案發出許多小型I/O要求的程式,往往會進行用戶緩衝式I/O。這是指在用戶空間進行緩衝(buffering) : 這可能是由應用程式自行完成,或是在程式庫中自動完成,而不是由核心來完成。(p73)
。在標準I/O用語中,一個已開啟檔案稱為串流(stream)。串流可能會被開啟以備讀取(輸入串流)、寫出(輸出串流)或讀寫(輸出入串流)。(p77)
。I/O級別較高,讀寫時使用「緩衝」。
。「fopen系列」是由「open系列」擴充而來,較常使用「fopen系列」(因為較容易移植)
。標準輸入(Standard Input)、標準輸出(Standard Output)、標準錯誤(Standard Error)
https://imwalter8.blogspot.com/2020/05/standard-inputstandard-outputstandard.html
。sample code :
https://github.com/walter-cc/Linux_Device_Driver/commit/8a9797c62677d8d63496de16a31640d88801ccb1
# 參考文件 :
- Linux 系統程式設計, 2/e(內容涵蓋 Linux Kernel 3.0),Robert Love 著、蔣大偉 譯
Linux System Programming: Talking Directly to the Kernel and C Library)
- Linux 文件描述符简介(file descriptor)
https://blog.csdn.net/Artprog/article/details/60601253
- Linux 系統程式設計 - fd 及 open()、close() 系統呼叫
https://blog.jaycetyle.com/2018/12/linux-fd-open-close/
- open fopen CreatFile 區別
https://www.itread01.com/content/1541950693.html
- C语言中open与fopen的的解释和区别
https://blog.csdn.net/LEON1741/article/details/78091974
- Linux C中的open函數
https://blog.csdn.net/weixin_39296438/article/details/79422068
- 標準輸入(Standard Input)、標準輸出(Standard Output)、標準錯誤(Standard Error)
https://imwalter8.blogspot.com/2020/05/standard-inputstandard-outputstandard.html


留言
張貼留言