深入理解Linux文件I/O:系統調用與標志位應用

目錄

一、引入

二、標志位

1、什么是標志位?

2、標志位傳遞示例?

輸出結果分析

關鍵點解釋

三、文件描述符(File Descriptor)(先大概了解)

四、接口介紹:open()函數

1、命令查看

2、頭文件

3、函數原型

4、參數說明

1. open的第一個參數pathname

2. open的第二個參數

1. 必需標志(必須指定且只能指定一個)

2. 可選標志(可組合使用)

補充說明

擴展:

3. open的第三個參數

基本權限位

特殊權限位

如何使用?mode_t?

1. 直接使用八進制數

2. 使用宏定義組合

3. 設置特殊權限

mode_t?的實際影響

5、返回值

五、接口介紹:close()函數

1、函數原型

2、參數說明

3、返回值

4、常見錯誤碼(errno)

5、基本用法

6、深入理解close操作(了解)

7、注意事項(了解)

六、接口介紹:write()函數

1. write函數原型

2. 參數說明

3. 返回值

4、對文件進行寫入操作示例

5. write函數的特點和注意事項

1.?部分寫入

2. 阻塞與非阻塞

3. 原子性

4. 文件位置指針

七、接口介紹:read()函數

1、函數原型

2、參數說明

3、返回值

4、對文件進行讀取操作示例

八、系統調用和庫函數


一、引入

????????操作系統提供多種文件訪問方式,包括C語言接口、C++接口以及其他語言接口,同時也具備底層系統調用接口,系統調用才是文件操作最底層的實現方式。相較于高級語言庫函數,系統調用更接近底層硬件。實際上,各種語言的庫函數都是對系統接口的封裝實現。

????????無論是在Linux還是Windows平臺運行C代碼,C庫函數都通過封裝各自操作系統的系統調用接口來實現跨平臺性。這種設計不僅保證了語言的通用性,也為二次開發提供了便利。

在學習系統文件I/O前,需要先掌握標志位的傳遞方法,這在系統文件I/O接口中會頻繁使用:


二、標志位

1、什么是標志位?

????????標志位(flag)是一種編程中常用的技術,它使用二進制位來表示不同的狀態或選項。每個標志位通常對應一個特定的含義,通過位運算可以單獨設置、清除或檢查這些標志位。

標志位的優點包括:

  • 節省內存(多個布爾狀態可以用一個整數的不同位表示)

  • 可以方便地組合多個狀態(通過位或運算)

  • 可以高效地檢查特定狀態(通過位與運算)

2、標志位傳遞示例?

#include <stdio.h>// 定義三個標志位,每個標志位對應一個不同的二進制位
#define ONE   0x01    // 0000 0001 (二進制)
#define TWO   0x02    // 0000 0010
#define THREE 0x04    // 0000 0100void func(int flags) {// 檢查flags是否包含ONE標志if (flags & ONE) printf("flags has ONE!\n");// 檢查flags是否包含TWO標志if (flags & TWO) printf("flags has TWO!\n");// 檢查flags是否包含THREE標志if (flags & THREE) printf("flags has THREE!\n");printf("\n");
}int main() {func(ONE);                  // 只傳遞ONE標志func(THREE);                // 只傳遞THREE標志func(ONE | TWO);            // 傳遞ONE和TWO標志的組合func(ONE | THREE | TWO);    // 傳遞所有三個標志的組合return 0;
}

輸出結果分析

  1. func(ONE);?輸出:flags has ONE!(只有ONE標志被設置)

  2. func(THREE);?輸出:flags has THREE!(只有THREE標志被設置)

  3. func(ONE | TWO);?輸出:

    flags has ONE!
    flags has TWO!(ONE和TWO標志被設置)
  4. func(ONE | THREE | TWO);?輸出:

    flags has ONE!
    flags has TWO!
    flags has THREE!(所有三個標志都被設置)

關鍵點解釋

  1. flags & ONE:這是一個位與運算,用于檢查flags變量中是否設置了ONE標志位。如果結果為非零,則表示設置了該標志。

  2. ONE | TWO:這是一個位或運算,用于組合多個標志位。結果是一個同時包含ONE和TWO標志的值。

  3. 標志位的值選擇:每個標志位對應一個不同的二進制位(0x01, 0x02, 0x04等),這樣它們可以獨立設置和檢查而不會相互干擾。

這種標志位技術在系統編程、硬件接口和需要高效表示多個選項的場景中非常常見。


三、文件描述符(File Descriptor)(先大概了解)

????????在Unix/Linux系統中,所有I/O操作都是通過文件描述符完成的。文件描述符是一個非負整數,用于標識打開的文件。系統為每個進程維護一個文件描述符表。

三個標準的文件描述符:

  • 0: 標準輸入(stdin)

  • 1: 標準輸出(stdout)

  • 2: 標準錯誤(stderr)


四、接口介紹:open()函數

? ? open()函數是Linux/Unix系統中用于打開或創建文件的核心系統調用之一,它是文件操作的基礎。

1、命令查看

man 2 open

2、頭文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

3、函數原型

系統接口中使用open函數打開文件,open函數的函數原型如下:

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

4、參數說明

1. open的第一個參數pathname

????????open函數的第一個參數是pathname,表示要打開或創建的文件路徑名,可以是相對路徑或絕對路徑。

  • 若pathname以路徑的方式給出,則當需要創建該文件時,就在pathname路徑下進行創建。
  • 若pathname以文件名的方式給出,則當需要創建該文件時,默認在當前路徑下進行創建。(注意當前路徑的含義)

2. open的第二個參數

????????open函數的第二個參數是flags(文件打開方式標志位),表示打開文件的標志,控制文件的打開方式和行為。flags參數由以下一個或多個值通過位或(|)操作組合而成。

????????例如,若想以只寫的方式打開文件,但當目標文件不存在時自動創建文件,則第二個參數設置如下:

O_WRONLY | O_CREAT
1. 必需標志(必須指定且只能指定一個)
標志說明
O_RDONLY只讀方式打開文件
O_WRONLY只寫方式打開文件
O_RDWR讀寫方式打開文件
2. 可選標志(可組合使用)
標志說明
O_CREAT如果文件不存在,則創建它(需配合?mode?參數設置權限)
O_EXCL與?O_CREAT?一起使用,確保文件不存在時才創建(用于原子性創建文件)
O_TRUNC如果文件已存在且是普通文件,則截斷為0字節(清空文件)
O_APPEND追加模式,每次寫入都會自動追加到文件末尾(避免并發寫入沖突)
O_NONBLOCK?/?O_NDELAY非阻塞模式打開文件(適用于 FIFO、管道、設備文件等)
O_SYNC同步 I/O,每次寫操作都會等待數據真正寫入物理存儲(性能較低,但數據更安全)
O_NOFOLLOW如果路徑是符號鏈接,則不跟隨(防止符號鏈接攻擊)
O_DIRECTORY如果路徑不是目錄,則打開失敗(確保只打開目錄)
O_CLOEXEC設置?close-on-exec?標志,exec 時自動關閉文件描述符(防止子進程繼承)

補充說明

  • 必需標志O_RDONLY?/?O_WRONLY?/?O_RDWR)必須選且僅選一個

  • 可選標志可以通過?|(按位或)組合使用,例如:

    int fd = open("file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
  • O_EXCL?必須與?O_CREAT?一起使用,否則無意義。

  • O_TRUNC?僅對普通文件有效,對目錄、設備文件等無效。

  • O_APPEND?在多進程/多線程寫入時能避免競爭條件(Race Condition)。

  • O_SYNC?會影響性能,但能確保數據持久化(適用于關鍵數據存儲)。

擴展:

????????系統接口open的第二個參數flags是整型,有32比特位,若將一個比特位作為一個標志位,則理論上flags可以傳遞32種不同的標志位。

實際上傳入flags的每一個選項在系統當中都是以宏的方式進行定義的:

例如,O_RDONLY、O_WRONLY、O_RDWR和O_CREAT在系統當中的宏定義如下:

#define O_RDONLY ? ? ? ? 00
#define O_WRONLY ? ? ? ? 01
#define O_RDWR ? ? ? ? ? 02
#define O_CREAT ? ? ? ?0100

????????這些宏定義選項的二進制編碼具有一個共同特征:每個選項的二進制序列中僅有一位為1(O_RDONLY選項除外,其二進制值為全0,表示默認選項)。不同選項的置1位各不相同,這使得open函數內部可以通過簡單的"與"運算來檢測特定選項是否被設置。

int open(arg1, arg2, arg3)
{if (arg2&O_RDONLY)//檢查是否設置了O_RDONLY選項{}if (arg2&O_WRONLY)//檢查是否設置了O_WRONLY選項{}if (arg2&O_RDWR)//檢查是否設置了O_RDWR選項{}if (arg2&O_CREAT)//檢查是否設置了O_CREAT選項{}//...
}

3. open的第三個參數

????????在 Unix/Linux 系統調用中,mode_t?是一個數據類型,用于表示文件的權限模式(permission mode)。它通常是一個無符號整數類型(如?unsigned int),用于指定文件的訪問權限。

????????當使用O_CREAT創建新文件時,必須指定mode參數,表示新文件的權限。mode通常用八進制表示,如0644。

例如,設置mode=0666會賦予文件-rw-rw-rw-的權限。

????????需要注意的是,實際文件權限會受到umask(文件創建掩碼)的影響。計算公式為:實際權限 = mode & (~umask)。在默認umask=0002的情況下,當mode=0666時,實際創建的權限為0664(即-rw-rw-r--)。

若要完全按照mode參數設置權限,可以在創建文件前調用umask(0)將掩碼清零。

umask(0); //將文件默認掩碼設置為0

注意:?當不需要創建文件時,open的第三個參數可以不必設置。?

? ? open()?函數在創建文件(使用?O_CREAT?標志)時,需要指定文件的權限模式?mode_t。這個參數決定了文件的讀、寫、執行權限,以及特殊權限位(如 setuid、setgid 等)。

基本權限位

mode_t?由多個權限位組合而成,可以使用八進制數或宏定義來設置:

宏定義八進制值權限說明
S_IRUSR0400用戶(owner)可讀
S_IWUSR0200用戶可寫
S_IXUSR0100用戶可執行
S_IRGRP0040組(group)可讀
S_IWGRP0020組可寫
S_IXGRP0010組可執行
S_IROTH0004其他用戶(others)可讀
S_IWOTH0002其他用戶可寫
S_IXOTH0001其他用戶可執行
特殊權限位
宏定義八進制值權限說明
S_ISUID04000設置用戶ID(setuid)
S_ISGID02000設置組ID(setgid)
S_ISVTX01000粘滯位(sticky bit)
如何使用?mode_t
1. 直接使用八進制數

最常見的用法是直接使用?3位八進制數?來設置權限:

int fd = open("example.txt", O_CREAT | O_WRONLY, 0644);
  • 0644?表示:

    • 用戶(owner)64+2,即?rw-

    • 組(group)4r--

    • 其他用戶(others)4r--

2. 使用宏定義組合

也可以使用宏定義組合:

int fd = open("example.txt", O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  • 等同于?0644rw-r--r--

3. 設置特殊權限

例如,設置?setuid?權限(僅對可執行文件有效):

int fd = open("program", O_CREAT | O_WRONLY, S_IRWXU | S_ISUID);
  • S_IRWXU?=?0700rwx------

  • S_ISUID?=?04000(設置?setuid?位)

  • 最終權限:4700rws------

mode_t?的實際影響
  • open()?的?mode?參數僅在?O_CREAT?時生效(如果文件已存在,則不會修改權限)。

  • 最終權限會受到?umask?的影響:

    mode_t final_mode = mode & ~umask;

    例如,如果?umask=002,而?mode=0666,則實際權限是?0664rw-rw-r--)。

5、返回值

open函數的返回值是新打開文件的文件描述符。

  • 成功:成功時返回一個非負整數文件描述符。
  • 失敗:失敗時返回-1并設置errno。

我們可以嘗試一次打開多個文件,然后分別打印它們的文件描述符:?

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
int main()
{umask(0);int fd1 = open("log1.txt", O_RDONLY | O_CREAT, 0666);int fd2 = open("log2.txt", O_RDONLY | O_CREAT, 0666);int fd3 = open("log3.txt", O_RDONLY | O_CREAT, 0666);int fd4 = open("log4.txt", O_RDONLY | O_CREAT, 0666);int fd5 = open("log5.txt", O_RDONLY | O_CREAT, 0666);printf("fd1:%d\n", fd1);printf("fd2:%d\n", fd2);printf("fd3:%d\n", fd3);printf("fd4:%d\n", fd4);printf("fd5:%d\n", fd5);return 0;
}

運行程序后可以看到,打開文件的文件描述符是從3開始連續且遞增的:

我們再嘗試打開一個根本不存在的文件,也就是open函數打開文件失敗:?

#include <stdio.h>                                                                                       
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{int fd = open("test.txt", O_RDONLY);printf("%d\n", fd);return 0;
}

運行程序后可以看到,打開文件失敗時獲取到的文件描述符是-1:?

????????文件描述符本質上是一個指針數組的索引,該數組中的每個指針都指向一個已打開文件的文件信息。通過文件描述符即可訪問對應的文件信息。

????????當open函數成功打開文件時,系統會擴展指針數組并返回新增指針的索引值;若打開失敗則直接返回-1。因此,連續成功打開多個文件時,獲得的文件描述符是依次遞增的。

????????Linux進程默認打開三個標準文件描述符:0(標準輸入)、1(標準輸出)和2(標準錯誤)。這就是新打開文件時,文件描述符從3開始分配的原因。

open 函數的具體使用方式取決于應用場景:

  • 若目標文件不存在,需要創建新文件,則使用帶三個參數的 open(第三個參數表示創建文件的默認權限)
  • 若文件已存在,則使用帶兩個參數的 open

五、接口介紹:close()函數

close()函數是Linux/Unix系統中用于關閉已打開文件描述符的重要系統調用。

1、函數原型

#include <unistd.h>int close(int fd);

2、參數說明

fd(文件描述符)

????????要關閉的文件描述符(file descriptor),這是之前通過open()creat()pipe()dup()等函數獲得的文件描述符。

3、返回值

  • 成功時返回0

  • 失敗時返回-1,并設置errno來指示錯誤原因

4、常見錯誤碼(errno)

  • EBADF:fd不是有效的已打開文件描述符

  • EINTR:close操作被信號中斷

  • EIO:發生了I/O錯誤

5、基本用法

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>int main() {int fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("open failed");return 1;}// 使用文件描述符進行讀寫操作...if (close(fd) == -1) {perror("close failed");return 1;}return 0;
}

6、深入理解close操作(了解)

  1. 資源釋放

    • 關閉文件描述符會釋放內核為該文件分配的所有資源

    • 釋放文件描述符本身,使其可被后續的open()pipe()等調用重用

  2. 緩沖區刷新

    • 對于輸出文件,close操作會確保所有緩沖數據被寫入磁盤

    • 對于使用mmap()映射的文件,close操作不會解除映射,但關閉后訪問映射內存可能導致SIGBUS信號

  3. 文件鎖釋放

    • 進程終止時所有文件描述符會自動關閉

    • 關閉文件描述符會釋放該進程在該文件上設置的所有鎖(使用fcntl()設置的鎖)

7、注意事項(了解)

  1. 多次關閉

    • 重復關閉同一個文件描述符是錯誤行為

    • 在多線程環境中尤其需要注意,可能引發競態條件

  2. 信號中斷處理

    • 如果close()被信號中斷,某些系統上需要重新調用close()

    • 更安全的做法是使用以下模式:

      while (close(fd) == -1) {if (errno != EINTR) {perror("close error");break;}// 如果是被信號中斷,則繼續嘗試關閉
      }
  3. 文件描述符泄漏

    • 忘記關閉文件描述符是常見編程錯誤

    • 長期運行的進程可能導致文件描述符耗盡

    • 建議在打開文件后立即考慮關閉操作,使用goto或RAII模式管理資源。


六、接口介紹:write()函數

? ? write()?是Linux/Unix系統中一個非常重要的低級文件I/O函數,用于將數據寫入文件描述符對應的文件或設備。

1. write函數原型

#include <unistd.h>ssize_t write(int fd, const void *buf, size_t count);

2. 參數說明

  • fd:文件描述符,通常由open()函數返回

  • buf:指向要寫入數據的緩沖區的指針

  • count:要寫入的字節數

3. 返回值

  • 成功時:返回實際寫入的字節數(可能小于請求的count

  • 失敗時:返回-1,并設置errno

4、對文件進行寫入操作示例

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{int fd = open("log.txt", O_WRONLY | O_CREAT, 0666);if (fd < 0){perror("open");return 1;}const char* msg = "hello syscall\n";for (int i = 0; i < 5; i++){write(fd, msg, strlen(msg));}close(fd);return 0;
}

運行程序后,在當前路徑下就會生成對應文件,文件當中就是我們寫入的內容:

5. write函數的特點和注意事項

1.?部分寫入

write()可能會執行部分寫入,即返回值小于請求的字節數。這種情況常見于:

  • 磁盤空間不足

  • 被信號中斷

  • 非阻塞模式下資源暫時不可用

2. 阻塞與非阻塞

  • 常規文件通常不會阻塞

  • 管道、套接字等特殊文件可能阻塞

  • 可以設置O_NONBLOCK標志使操作非阻塞

3. 原子性

對于常規文件,小于PIPE_BUF大小的寫入是原子的(通常為4096字節)

4. 文件位置指針

write()操作會更新文件的當前位置指針


七、接口介紹:read()函數

? ? read()?函數是Linux/Unix系統中用于從文件描述符讀取數據的基本系統調用之一。它是文件I/O操作的核心函數之一,屬于POSIX標準的一部分。

1、函數原型

#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);

2、參數說明

  1. fd (file descriptor):文件描述符,是一個整數值,指向要讀取的文件

    • 通常由open()函數返回

    • 標準輸入的文件描述符是0

  2. buf:指向內存緩沖區的指針,用于存放讀取到的數據。必須預先分配足夠的內存空間

  3. count:請求讀取的字節數。通常是緩沖區的大小

3、返回值

  • 成功時:返回實際讀取的字節數

    • 可能小于請求的字節數(例如接近文件末尾時)

    • 返回0表示到達文件末尾(EOF)

  • 失敗時:返回-1,并設置errno

    • 常見的errno值:

      • EAGAIN/EWOULDBLOCK:非阻塞I/O且無數據可讀

      • EBADF:無效的文件描述符

      • EINTR:被信號中斷

      • EIO:I/O錯誤

4、對文件進行讀取操作示例

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{int fd = open("log.txt", O_RDONLY);if (fd < 0){perror("open");return 1;}char ch;while (1){ssize_t s = read(fd, &ch, 1);if (s <= 0){break;}write(1, &ch, 1); //向文件描述符為1的文件寫入數據,即向顯示器寫入數據}close(fd);return 0;
}

運行程序后,就會將我們剛才寫入文件的內容讀取出來,并打印在顯示器上:


八、系統調用和庫函數

????????總的來說,我們更加能明白開始時提到的“實際上,各種語言的庫函數都是對系統接口的封裝實現。”這句話!!!

在了解返回值之前,需要明確兩個重要概念:系統調用和庫函數

  • fopen、fclose、fread、fwrite這些是C標準庫提供的函數,稱為庫函數(libc)
  • 而open、close、read、write、lseek等則是操作系統直接提供的接口,稱為系統調用
  • 這與我們之前講解操作系統概念時展示的系統架構圖是一致的

????????系統調用接口與庫函數的關系十分清晰。可以明確地說,f#系列函數是對系統調用的封裝,為二次開發提供了便利。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/91683.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/91683.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/91683.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

海康線掃相機通過采集卡的取圖設置

目錄 1、掃描高度小于65000行 1.1 軟觸發 1、采集卡設置項 2、相機設置項 1.2 硬觸發 1、采集卡設置項 2、相機設置項 2、掃描高度大于65000行 1.1 軟觸發 1、采集卡設置項 2、相機設置 1.2 硬觸發 1、采集卡設置項 2、相機設置 2.1 幀掃描 2.2 行掃描 3、注意…

InfluxDB 3與Apache Parquet:打造高性能時序數據存儲與分析解決方案

在當今數據驅動的時代&#xff0c;各行業產生的數據量呈爆炸式增長&#xff0c;如何高效存儲和管理海量數據成為企業和開發者面臨的重大挑戰。對于時序數據而言&#xff0c;其具有數據量大、寫入頻繁、查詢模式多樣等特點&#xff0c;對存儲系統的性能和效率提出了更高的要求。…

20250718-4-Kubernetes 應用程序生命周期管理-Pod對象:實現機制_筆記

一、Pod對象&#xfeff;&#xfeff;1. 資源共享實現機制1&#xff09;共享網絡&#xfeff;基本概念實現方式&#xff1a;通過將業務容器網絡加入到負責網絡的容器&#xff08;infra container&#xff09;實現網絡共享核心特點&#xff1a;共享網絡協議棧&#xff08;包括TC…

防爆手機是什么?能用普通手機改裝嗎?

在石油開采平臺的井架之上&#xff0c;在化工車間的反應釜旁&#xff0c;在煤礦深達千米的巷道中&#xff0c;一群特殊的工作人員正使用著看似普通的通訊設備。這些設備外殼上醒目的Ex防爆認證標志&#xff0c;揭示著其與眾不同的身份——防爆手機。這類專為易燃易爆環境設計的…

gem install報錯解析

報錯內容 [rootlocalhost ~]# gem install bundler Fetching: bundler-2.6.9.gem (100%) ERROR: Error installing bundler:bundler requires Ruby version > 3.1.0. The current ruby version is 2.5.0.解決方案&#xff08;任選其一&#xff09; 這個錯誤表明你當前的 Ru…

css 如何實現大屏4個占位 中屏2個 小屏幕1個

1、 使用grid.container {display: grid;grid-template-columns: repeat(4, 1fr);gap: 20px;border: 1px solid red;width: 400px;height: 400px;}media (max-width: 768px) {.container {grid-template-columns: 1fr;}}media (min-width: 768px) and (max-width: 992px) {.con…

Redis學習系列之—— JDHotKey 熱點緩存探測系統

一、為什么需要熱點緩存探測 在回答這個問題前&#xff0c;我們先考慮一下&#xff1a;為什么光用 Redis 還不夠&#xff0c;還需要使用本地緩存&#xff1f; 一般來說&#xff0c;Redis 集群的性能能抗住幾十萬并發&#xff0c;能夠應付大部分情況。但對于一些頭部 APP&#x…

Linux 安全加固

Linux 安全加固需要從??用戶權限、系統服務、網絡防護、日志審計、文件系統、訪問控制??等多個維度入手&#xff0c;目標是減少攻擊面、限制未授權訪問、提升系統健壯性。以下是??詳細步驟實操示例??&#xff0c;覆蓋主流 Linux 發行版&#xff08;如 CentOS/Ubuntu&am…

【Docker#2】容器歷史發展 | 虛擬化實現方式

一、前言 – 容器技術發展史 容器技術是現今計算技術的重要組成部分&#xff0c;其發展歷程可以追溯到很早的計算機系統提供的進程隔離工具。以下是容器技術的發展歷程&#xff0c;其中涵蓋了從早期的進程隔離技術到現代云計算和云原生的演變&#xff1a; ① Jail 時代 1979 年…

React + Mermaid 圖表渲染消失問題剖析及 4 種代碼級修復方案

Mermaid 是一個流行的庫&#xff0c;它可以將文本圖表&#xff08;例如 graph LR; A-->B;&#xff09;轉換為 SVG 圖表。在靜態 HTML 頁面中&#xff0c;Mermaid 會查找 <pre class"mermaid"> 代碼塊&#xff0c;并在頁面加載時將它們替換為渲染后的圖表。它…

[Element]修改el-pagination背景色

[Element]修改el-pagination背景色 代碼 <el-pagination:current-page.sync"queryParams.current":page-size.sync"queryParams.size":page-sizes"[10, 20, 50, 100]"layout"prev, pager, next, jumper, sizes":total"queryP…

Docker 可用鏡像列表

Docker 鏡像源列表&#xff08;7月15日更新-長期&免費&#xff09;_dockerhub國內鏡像源列表-CSDN博客

低代碼可視化工作流的系統設計與實現路徑研究

一、背景分析在數字化轉型不斷深化的背景下&#xff0c;企業業務流程呈現出高度定制化與動態調整的趨勢&#xff0c;傳統信息系統在開發周期、實施成本與擴展能力上的局限性日益凸顯&#xff0c;已難以支撐快速響應和敏捷迭代的實際需求。面向這一現實挑戰&#xff0c;基于 BPM…

mac mlx大模型框架的安裝和使用

mlx是apple平臺的大模型推理框架&#xff0c;對mac m1系列處理器支持較好。 這里記錄mlx安裝和運行示例。 1 安裝mlx框架 conda create -n mlx python3.12 conda activate mlx pip install mlx-lm 2 運行mlx測試例 以下是測試程序&#xff0c;使用方法和hf、vllm等推理框架基…

JAVA 使用Apache POI合并Word文檔并保留批注的實現

一、需求背景 在實際工作中&#xff0c;我們經常需要將多個Word文檔合并成一個文件。但當文檔中包含批注&#xff08;Comments&#xff09;時&#xff0c;傳統的復制粘貼會導致批注丟失或引用錯亂。本文將介紹如何通過Java和Apache POI庫實現保留批注及引用關系的文檔合并功能。…

Linux的服務管理工具:`systemd`(`systemctl`)和`SysVinit ` 筆記250718

Linux的服務管理工具:systemd(systemctl)和SysVinit 筆記250718 Linux的服務管理工具 Linux 的服務管理工具隨著發行版和初始化系統的發展而演變。以下是主要的服務管理工具及其對應的初始化系統&#xff1a; 1. systemd (現代主流標準) 初始化系統&#xff1a; 是絕大多數…

Couchbase 可觀測性最佳實踐

Couchbase 介紹 Couchbase 是一個開源的分布式 NoSQL 數據庫&#xff0c;專為高性能和高可擴展性設計&#xff0c;適用于實時數據處理的企業應用。它結合鍵值存儲和文檔數據庫的優勢&#xff0c;支持 JSON 文檔存儲&#xff0c;并通過 N1QL&#xff08;類 SQL 查詢語言&#x…

構建基于MCP的LLM聊天機器人客戶端開發指南

引言 在當今人工智能技術快速發展的時代&#xff0c;大型語言模型(LLM)已成為構建智能應用的核心組件。MCP(Modular Conversational Platform)作為一個強大的對話平臺&#xff0c;為開發者提供了將LLM能力與自定義工具集成的標準化方式。本文將詳細介紹如何使用Python開發一個…

接口測試的原則、用例與流程詳解

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 一、接口的介紹軟件測試中&#xff0c;常說的接口有兩種&#xff1a;圖形用戶接口&#xff08;GUI&#xff0c;人與程序的接口&#xff09;、應用程序編程接口&am…

ubuntu 22.02 帶外進單用戶拯救系統

不停地按 F7 &#xff0c;然后進到 menu &#xff0c;選擇 ubuntu &#xff0c;然后按下 ESC &#xff0c;然后瞬間會刷一個 ubuntu 的選項&#xff08;默認是在第一的位置&#xff0c;直接快速按下 e&#xff09;即可進入單用戶模式。 找到類似 linux /boot/vmlinuz-xxx rootU…