結合 Go 讀 APUE-檔案共享
在公眾號 "別捉急" 上 同步了文章,並且可以點選原文連結閱讀:傳送門
檔案共享
UNIX 系統支援在不同程式間共享開啟檔案, 知識點:核心用於所有 I/O 的資料結構、原子操作。
概念性的 I/O 資料結構
核心用於所有 I/O 的資料結構,只是個概念性的,不一定適用,有個大體的輪廓就 OK。
- 程式表 (process table entry) 中的記錄
- 檔案表項 (file table entry)
- v節點表項 (v-node table entry)
這是一個 開啟檔案的核心資料結構
圖。開啟檔案
這個操作是一個程式, 每個程式在程式表中都有一個記錄,而 開啟檔案程式記錄
中包含一張開啟檔案描述符表, 包括:
- 檔案描述符標誌
- 指向一個檔案表項的指標
檔案描述符表用 Go 抽象如下表示:
type fd struct {
flags int
pointer *FileTableEntry
}
程式碼中 flags
的型別是隨便定義的(實際我沒查),由圖中看出 pointer
指向檔案表項 (file table entry), 核心為所有開啟檔案維持一張檔案表, 每個檔案表項包括:
- 檔案狀態標誌 (讀、寫、添寫、同步和非阻塞)
- 當前檔案偏移量
- 指向該檔案 v 節點表項的指標
檔案表項用 Go 抽象如下表示:
type FileTableEntry struct {
status int
offset int
pointer *VNodeTableEntry
}
由圖中看出 pointer
指向v節點表項 (v-node table entry), 每個開啟檔案都有一個 v 節點結構如下所示:
- 檔案型別和對此檔案進行各種操作函式的指標,統稱為 v節點資訊
- 該檔案的 i 節點: 檔案所有者、檔案長度、指向檔案實際資料塊在磁碟上所在位置的指標等
V 節點表項和 i 節點用 Go 抽象如下:
type VNodeTableEntry struct {
information *Information
vData *INode
}
type INode struct {
owner *Owner
length int
vNodeTableEntry *VNodeTableEntry
}
通過這種方式,來加深對 核心通用 I/O 資料結構
的理解。
如果兩個獨立程式各自開啟同一個檔案,則三者關係如下所示:
原子操作
一般而言,原子操作 (atomic operation) 指的是由多步組成的一個操作。如果該操作原子地執行,則要麼執行完所有步驟,要麼一步也不執行,不可能只執行所有步驟的一個子集。
函式 dup 和 dup2
下面兩個函式都可用來複制一個現有的檔案描述符。
#include <unistd.h>
int dup(int fd);
int dup2(int fd, int fd2);
上面函式中的引數:
- fd 表示要複製的檔案描述符
- fd2 表示複製後的檔案描述符
dup2
函式是可以指定複製後的檔案描述符,而 dup
是返回當前可用檔案描述符中的最小數值。
呼叫 dup(1)
函式後,程式表項,檔案表,v 節點表,之間的關係圖如下:
對於傳入的引數 fd2, 已經被開啟了,會先關閉。知道了這個點,就明白了,下面的操作中會先呼叫 close(fd2)
。
很不爽了,沒找到相應的 Go 的原始碼。複製一個描述符的另一種方法是使用 fcntl函式
, dup2(fd, fd2)
等效於 close(fd2)
和 fcntl(fd, F_DUPFD, fd2)
, 但不完全等效,因為 dup2(fd, fd2)
是個原子操作。
目前我先知道 fcntl函式
可以改變已經開啟檔案的屬性,就可以啦。
相關文章
- 結合 Go 讀 APUE-基本檔案I/OGo
- go配置檔案讀取Go
- go–讀取檔案的方式Go
- go 讀取.ini配置檔案Go
- Go讀取yaml檔案到struct類GoYAMLStruct
- SpringBoot--SpringBoot 讀取Properties檔案(結合JDBC)Spring BootJDBC
- Go 專案配置檔案的定義和讀取Go
- samba共享檔案Samba
- CIFS檔案共享
- 零拷貝讀取檔案成 Go 物件Go物件
- flex結合servlet檔案上傳FlexServlet
- C#讀寫檔案總結C#
- C++檔案讀寫總結C++
- 清華尹成帶你實戰GO案例(27)Go 讀取檔案Go
- 使用Samba共享檔案Samba
- Mac檔案共享工具Mac
- 檔案共享之nfsNFS
- 檔案共享服務
- Pandas之EXCEL資料讀取/儲存/檔案分割/檔案合併Excel
- 如何實現檔案共享,檔案共享的設定方法-鐳速
- go學習之檔案讀取問題(需更新)Go
- EXE檔案結構及讀取方法
- Hive表小檔案合併方法總結Hive
- Go檔案操作Go
- 用 Git 來共享檔案Git
- NFS網路檔案共享NFS
- Windows檔案共享LinuxWindowsLinux
- FTP檔案共享服務FTP
- cifs檔案系統{samba檔案共享服務}Samba
- Yaml檔案語法及讀寫小結YAML
- 將檔案讀取到連結串列裡面
- Golang:go-humanize將檔案大小轉換成Kb、Mb、Gb適合人類閱讀的單位Golang
- Vagrant 開啟 smb 檔案共享
- 如何共享印表機和檔案
- FileProvider共享檔案、快取IDE快取
- 共享檔案和文件方法指南
- 29 檔案共享與保護
- ubuntu 16.04 samba 檔案共享UbuntuSamba