** 用戶態緩衝區**:我們通常所說的緩衝區是文件流指針結構體中定義的緩衝區。
上面的printf和fwrite是庫函數,write和10/0會處於內核態,產生異常。
文件系統:Linux下的ext2文件系統爲例,文件系統就是磁盤上管理文件的系統
存儲一個文件需要找到空閒的磁盤塊存儲文件數據,以及需要找到一個未被使用的inode節點存儲自己的源信息,針對每一個磁盤塊做一個整體的位圖,就可以快速找到空閒的磁盤塊。
文件的權限就是使用位圖存儲,一個用戶有沒有權限也就是0或1的關係,位圖可節省大量的空間以及二進制的與或非速度是非常快。
文件節點號就是前面的這串數字:
位圖:一連串二進制比特位,用來做一種數據標記。
文件的存儲流程:
- 通超級塊找到inode位圖/數據塊位圖,通過數據塊位圖快速的找到空閒的磁盤存儲文件數據;
- 通過inode位圖快速找到空閒的inode節點存儲文件的源信息;(文件數據存儲完畢),每個文件都有一個唯一的inode節點;
- 文件的數據儲存完畢後,還需要在這個文件的所在目錄下(目錄文件中),記錄每個文件名稱以及inode節點號(目錄項)。
獲取文件數據流程:通過文件名打開一個文件,在所在目錄文件中通過文件名找到這個文件的inode節點號,在磁盤超級塊中找到inode節點區域,根據inode節點號快速找到inode節點,得到數據存儲的磁盤塊號,取出數據。
軟鏈接文件/硬鏈接文件
給一個源文件創建一個軟鏈接文件/硬鏈接文件,就可以通過被創建出來的軟鏈接文件/硬鏈接文件來操作源文件
爲源文件創建一個硬鏈接文件:ln test.txt test.hard
爲源文件創建一個軟鏈接文件:In -s test.txt text.soft
軟鏈接文件和硬鏈接文件的區別
- 硬鏈接文件:本質上和源文件沒什麼區別,都是一個文件名稱,與源文件共用同一個inode節點,通過自己的inode節點訪問源文件數據;
- 軟鏈接文件:本質上是一個獨立的文件,有自己的inode節點,文件數據中保存源文件的路徑,通過這個路徑訪問源文件的數據;
區別: - 刪除源文件,軟鏈接文件失敗,硬鏈接文件只是鏈接數-1;(鏈接數:一個inode節點對應有幾個目錄項),刪除一個文件,文件並不會立即被刪除,而是直接刪除了目錄項信息,inode中的鏈接數-1,之後鏈接數爲0時,纔會真正刪除文件;
- 軟鏈接文件可以跨分區,硬鏈接文件不可以;(每個磁盤分區都有自己的文件系統,有自己的文件系統就意味着有自己的一套inode節點),(跨分區:建立硬鏈接,與文件inode節點號相同,這個inode節點號到底指向的是那個分區的inode節點);
- 軟鏈接文件可以對目錄創建,硬鏈接文件不可以;(Linux下目錄結構是唯一的,分區可以有多個,可以掛在不同的目錄上,目錄本身就是跨分區的,因此硬鏈接不能對目錄進行創建);
靜態庫和動態庫的打包與使用
庫文件:打包了一堆實現了常用功能的代碼文件。
將各個 .c 文件編譯彙編成目標文件, gcc -c child.c -o child.o
動態庫的打包:gcc -c -fPIC child.c -o child.o -> gcc -shared child.o -o libmychild.so; (動態庫的命名方式lib*.so**);
靜態庫的打包:gcc -c child.c -o child.o ->ar -cr ibmychild.a child.o (靜態庫的命名方式lib*.a);
庫的使用
生成可執行程序時鏈接使用:gcc main.c -o main -mychild (-l是指庫名稱)
- 必須將庫文件放到指定路徑下:/user/lib64 或者 /user/lib
- 設置連接庫的搜索路徑環境變量,將當前庫文件所在的路徑添加進去:export LIBRARY_PATH=$LIBRARY_PATH:.
- 使用gcc -L選項指定連接庫的搜索路徑:gcc main.c -o main -L./-lmychild
ldd main 查看main這個可執行程序依賴的動態庫
** 運行可執行程序時加載使用:僅僅對動態庫纔會在運行時加載庫文件**
- 必須將庫文件放到指定路徑下:/user/lib64 或者 /user/lib
- 設置連接庫的搜索路徑環境變量,將當前庫文件所在的路徑添加進去:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
靜態庫的鏈接:
- 將靜態庫放到指定的路徑下,然後使用-L指定靜態庫的位置(常用):gcc main.c -o main -L./lib -lmychild
- 對於所有的庫都使用靜態鏈接(很少用):gcc -static main.c -o main -L./lib -lmychild