文章目錄
簡 述: 講解在 Unix / Linux
下,man
手冊的使用;寫了一個例子調用系統庫函數來讀寫文本文件,和打印文件描述符;阻塞和非阻塞實際是文件的屬性,而非標準輸入輸出的 I/O 函數的屬性。 以及文件詳細描述的 stat
命令和 stat()
函數的使用;文件屬性相關的操作;文件夾遍歷和創建、刪除的相關函數,可能 Linux
有時候會調用到他們,現在實際上,更多的使用 Qt 的庫來對文件進行讀寫操作;以及關於複製文件描述符的函數 dup()
函數的講解
編程環境:
💻: uos20
📎 gcc/g++ 8.3
📎 gdb8.0
💻: MacOS 10.14
📎 gcc/g++ 9.2
📎 gdb8.3
man 手冊的使用:
-
man 2 open
在第二章裏面,精確查找 open 函數 -
man man
查看 man 手冊的大致介紹 (Linux 下) -
mac 下安裝中文 man 文檔:Mac配置中文 man 手冊
系統函數讀寫文件:
如下爲 Unix / Linux系統的庫函數:
-
open()
:打開文件 -
read()
:對文件進行讀操作 -
write()
:對文件進行寫操作 -
lseek()
:移動文件指針;擴展文件大小(移動指針後,要進行一次寫操作)-
文件指針移動到頭部:lseek(fd, 0, SEEK_SET);
-
文件指針移動到尾部:lseek(fd, 0, SEEK_END);
-
文件指針移動到當前位置:lseek(fd, 0, SEEK_SUR);
-
文件大寫爲 100K, 擴展到 1000K:
lseek(fd, 1000, SEEK_END); //文件指針從文件尾部偏移 1000 大小,這部分用^@ 填充佔位 wrire(fd, "a", 1); //隨便寫一個什麼到文件中,進行一次寫操作
-
-
全局變量 errno
:對於調用系統函數對文件進行讀寫操作,函數會返回一個錯誤 int 類型的數值。而 errno 變量就是不同的錯誤返回值的含義打印出來(字符串),使得人類可以看懂。調用方法:perror("[註釋信息: ]");
寫一例子:
-
將
Linux
系統的函數,調用open
、printf
、read
寫一個例子: -
編寫代碼如下:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <errno.h> int main() { int fp = open("hello.txt", O_RDWR); int fp2 = open("temp.txt", O_WRONLY | O_CREAT, 0777); //創建文件時候,必須要有權限 printf("fp = %d\n", fp); printf("fp2 = %d\n", fp2); if (fp == -1) perror("[註釋信息: ]"); //如果返回錯誤,會打印人類可讀懂的出字符串 char buf[4096]; int len = read(fp, buf, sizeof(buf)); while (len > 0) { int ret = write(fp2, buf, len); len = read(fp, buf, sizeof(buf)); printf("ret = %d\n", ret); } close(fp); close(fp2); return 0; }
-
編譯:
g++-9 main.cpp -o main
-
運行:其中 fp 便是打開文件 hello.txt 的文件描述符(因爲 0、1、2 被 stdin、stdout、stdout 佔了,所以最小就是 3);然後當打開第二個文本文件 temp.txt 的時候,其返回的文件描述符自然就是 4。關於文件描述符,詳細原理解釋可參考 此篇 。
源碼下載: 07_sysfun
阻塞和非阻塞:
終端程序: bash 爲前臺程序,當執行 a.out 程序時候,bash 就成爲了後臺程序,a.out 成爲了前臺程序(代碼執行到,等待輸入);當鍵盤輸入完成,a.out 成爲了後臺程序,bash 成爲了前臺程序。
當輸入的長度 大於 buf[10] 中的 10 時候, 多餘的部分就會成爲後面的命令輸入。
將下面的兩種,手動敲一遍。
阻塞 和 非阻塞 情況下,是文件的屬性,而非標準輸入輸出的 I/O 函數的屬性。
-
普通文件:hello.cpp
- 默認是非阻塞
-
終端設備 /dev/tty (默認是阻塞)
- 終端
- 管道
- 套接字
stat / lstat 函數 :
-
寫一個小的程序,判斷
ls -l
命令,基本可以實現 改用 switch() -
lstat
和stat
函數對於鏈接 l 的區別不一樣。- lstat 讀取的是鏈接文件, 本身的屬性
- stat 讀取的是鏈接文件指向的文件的屬性 (也被稱呼:追蹤,穿透)
- fstat 第一個參數是指文件描述符
#對應的 stat 命令:
作用:顯示文件或文件系統的狀態
uinx: stat -x hello.txt
linux: stat hello.txt
運行命令可以看到:hell.txt 文件的所有信息
由 ls -l hello.txt
查看看的,前面的 -rwxrwxrwx
就是表示下圖的 文件類型 、文件所有者權限 、文件所屬組權限 、其他人對該文件的權限 ,
- 其用 含義就是如下:
- 其在代碼裏面,用 struct 所表示的爲:
st_ mode -- 16位整數
0-2 bit--其他人權限
- S_IROTH 00004 讀權限
- S_IWOTH 00002 寫權限
- S_IXOTH 00001 執行權限
- S_IRIvxO 00007 掩碼,過濾 st_mode 中除其他人權限以外的信息
3-5 bit --所屬組權限
-S_IRGRP 00040 讀權限
-S_IWGRP 00020 寫權限
-S_IXGRP 00010 執行權限
-S_IRWXG 00070 掩碼,過濾 st_mode 中除所屬組權限以外的信息
6-8 bit --文件所有者權限
-S_IRUSR 00400 讀權限
-S_IWUSR 00200 寫權限
-S_IXUSR 00100 執行權限
-S_IRWXU 00700 掩碼,過濾 st_mode 中除文件所有者權限以外的信息。
12-15 bit --文件類型
-S_IFSOCK 0140000 套接字
-S_IFLNK 0120000 符號鏈接(軟鏈接)
-S_IFREG 0100000 普通文件
-S_IFBLK 0060000 塊設備
-S_IFDIR 0040000 目錄
-S_IFCHR 0020000 字符設備
-S_IFIFO 0010000 管道
-S_IFMT0 0017000 掩碼,過濾 st_mode 中除文件類型以外的信息
// 命令對應的函數
int stat(const char *path, struct stat *buf);
int Istat(const char *path, struct stat *buf);
文件屬性相關的函數:
access()
判斷傳入的文件,所具有的(讀、寫、執行、是否存)的權限chmod()
修改文件權限chown()
修改文件所有者和所屬組truncate()
修改文件大小^@
文件空洞, 填充佔位符號,實際就是\0
目錄操作相關函數:
目錄操作相關函數:
rename()
文件重命名chdir()
修改 當前進程(應用程序)的路徑;cdgetcwd()
獲取當前進程的工作目錄;pwdmkdir()
創建目錄;mkdirrmdir()
刪除一個空目錄;rm
目錄遍歷相關函數:
opendir()
打開一個目錄readdir()
讀目錄(進入子目錄,需要手動創建遞歸函數)close()
關閉目錄
dup / dup2 / fcntl 函數:
dup()
複製文件描述符dup2()
同上,形參不同(也會稱爲 參數 2:文件描述符的重定向)fcntl()
修改文件的狀態標誌
下載地址:
https://github.com/xmuli/linuxExample
歡迎 star 和 fork 這個系列的 linux 學習,附學習由淺入深的目錄。