C++-linux 7.文件IO(三)文件元數據與 C 標準庫文件操作

文件 IO 進階:文件元數據與 C 標準庫文件操作

在 Linux 系統中,文件操作不僅涉及數據的讀寫,還包括對文件元數據的管理和高層庫函數的使用。本文將從文件系統的底層存儲機制(inode 與 dentry)講起,詳細解析文件元數據獲取函數 stat,并全面介紹 C 標準庫中常用的文件操作函數(fopenfclose 及各類讀寫函數),幫助你掌握用戶態文件操作的核心邏輯與最佳實踐。

一、文件存儲基礎:inode 與 dentry

要理解文件操作的本質,需先掌握 Linux 文件系統中兩個核心概念——inode 和 dentry,它們是文件識別、路徑解析和元數據存儲的基礎。

1.1 inode:文件的“數字身份證”

inode(索引節點)是文件系統中存儲文件元數據的基本單位,本質是一個內核結構體,記錄了除文件名外的所有文件關鍵信息。

核心特性:
  • 唯一性:每個文件(包括普通文件、目錄、設備文件、管道等)在同一文件系統中對應唯一的 inode 編號(st_ino),即使文件名修改,inode 編號不變。
  • 持久化存儲:inode 存儲在磁盤上,包含文件的核心屬性,是文件的“身份證”,而文件名僅是指向 inode 的“別名”。
  • 元數據內容:包括文件類型、權限(st_mode)、所有者(st_uid/st_gid)、文件大小(st_size)、時間戳(訪問/修改/狀態變更時間)、磁盤塊位置等關鍵信息。
為何需要 inode?
  • 實現“硬鏈接”:多個文件名可指向同一 inode(通過 ln 命令創建),共享數據和權限,刪除一個文件名不影響 inode 及其他鏈接。
  • 高效文件訪問:內核通過 inode 直接定位磁盤數據,無需遍歷文件名,大幅提升文件操作效率。

1.2 dentry:路徑解析的“導航地圖”

dentry(目錄項)是 Linux 內核在內存中維護的臨時緩存結構,用于加速文件路徑的解析過程。

核心特性:
  • 內存級緩存:dentry 不持久化存儲在磁盤,僅存在于內存的 dentry 緩存(dcache)中,隨系統運行動態創建和銷毀。
  • 映射關系:記錄“文件名 → inode 編號”的映射,以及路徑的層級關系(例如解析 /home/user/test.txt 時,需逐級匹配目錄的 dentry)。
  • 核心作用:減少磁盤訪問次數,加速路徑解析。例如首次訪問某路徑后,dentry 會緩存映射關系,后續訪問無需重復查詢磁盤 inode。
inode 與 dentry 的關系:
  • inode 是文件的“身份證”(持久化元數據),dentry 是“導航圖”(內存級路徑映射)。
  • 路徑解析流程:內核通過 dentry 緩存逐級查找文件名對應的 inode,若緩存未命中,則從磁盤讀取目錄 inode 并更新緩存,最終定位到目標文件。

二、stat 函數:獲取文件元數據的標準接口

stat 函數是用戶態程序獲取文件元數據(存儲在 inode 中)的核心接口,無需直接操作 inode,即可獲取文件類型、權限、大小等關鍵信息。

2.1 函數原型與功能

#include <sys/stat.h>// 通過路徑名獲取文件元數據
int stat(const char *pathname, struct stat *buf);
// 通過文件描述符獲取文件元數據(更高效,避免路徑解析)
int fstat(int fd, struct stat *buf);
// 獲取符號鏈接本身的元數據(不跟隨鏈接指向的文件)
int lstat(const char *pathname, struct stat *buf);
功能:

讀取文件的元數據(如 inode 信息、權限、時間戳等),并存儲到 struct stat 結構體中。

2.2 參數與返回值

  • pathname:目標文件的路徑名(絕對或相對路徑,如 "/etc/passwd")。
  • fd:已打開的文件描述符(fstat 專用)。
  • buf:傳出參數,指向預分配的 struct stat 結構體,用于存儲獲取的元數據。
  • 返回值:成功返回 0;失敗返回 -1,并設置 errno(如 ENOENT 表示文件不存在,EACCES 表示權限不足)。

2.3 關鍵數據結構:struct stat

struct stat 結構體包含文件的所有元數據,核心字段如下:

字段類型含義說明
st_inoino_t文件的 inode 編號(唯一標識)。
st_modemode_t文件類型(如普通文件、目錄)和權限位(如 0755 表示 rwxr-xr-x)。
st_uiduid_t文件所有者的用戶 ID(UID)。
st_gidgid_t文件所有者的組 ID(GID)。
st_sizeoff_t文件大小(字節數,僅對普通文件有效)。
st_blksizeblksize_t文件系統的最佳 I/O 塊大小(按此大小讀寫可提高效率)。
st_blocksblkcnt_t文件占用的磁盤塊數(每塊通常為 512 字節)。
st_atimetime_t最后訪問時間(如 read 操作觸發更新)。
st_mtimetime_t最后修改時間(如 write 操作修改內容時觸發更新)。
st_ctimetime_t最后狀態變更時間(如權限、所有者修改時觸發更新,區別于內容修改)。
st_nlinknlink_t硬鏈接數量(ln 命令創建的鏈接數,文件刪除需此值減為 0)。

2.4 核心用法:通過 st_mode 判斷文件類型

st_mode 的高 4 位標識文件類型,可通過以下宏快速判斷:

含義適用場景
S_ISREG(m)是否為普通文件判斷常規數據文件
S_ISDIR(m)是否為目錄判斷文件夾
S_ISCHR(m)是否為字符設備文件判斷終端、串口等字符設備
S_ISBLK(m)是否為塊設備文件判斷硬盤、U盤等塊設備
S_ISLNK(m)是否為符號鏈接lstat 可檢測
S_ISFIFO(m)是否為管道文件判斷匿名/命名管道
S_ISSOCK(m)是否為套接字文件判斷網絡套接字

(注:mstruct stat 中的 st_mode 字段)

2.5 編程示例:使用 stat 獲取文件信息

#include <stdio.h>
#include <sys/stat.h>
#include <time.h>  // 用于 ctime 轉換時間戳int main() {const char *file_path = "/etc/passwd";struct stat file_info;// 獲取文件元數據if (stat(file_path, &file_info) == -1) {perror("stat failed");  // 輸出錯誤原因(如文件不存在)return 1;}// 打印基礎信息printf("文件路徑:%s\n", file_path);printf("inode 編號:%ld\n", (long)file_info.st_ino);printf("文件大小:%ld 字節\n", (long)file_info.st_size);printf("硬鏈接數量:%ld\n", (long)file_info.st_nlink);printf("所有者 UID:%ld,組 GID:%ld\n", (long)file_info.st_uid, (long)file_info.st_gid);// 解析權限(通過 &0777 提取后 9 位權限位)printf("文件權限:%o(八進制)\n", file_info.st_mode & 0777);// 解析時間戳(轉換為本地時間字符串)printf("最后訪問時間:%s", ctime(&file_info.st_atime));printf("最后修改時間:%s", ctime(&file_info.st_mtime));printf("最后狀態變更時間:%s", ctime(&file_info.st_ctime));// 判斷文件類型if (S_ISREG(file_info.st_mode)) {printf("文件類型:普通文件\n");} else if (S_ISDIR(file_info.st_mode)) {printf("文件類型:目錄\n");} else if (S_ISCHR(file_info.st_mode)) {printf("文件類型:字符設備\n");}return 0;
}
輸出說明:

運行后將打印 /etc/passwd 的 inode 編號、大小、權限等信息,若文件不存在則輸出 stat failed: No such file or directory

三、C 標準庫文件操作函數詳解

C 標準庫提供了一套封裝底層系統調用的文件操作函數,基于“文件流(FILE*)”實現,自帶緩沖區,簡化了文件讀寫流程,是用戶態文件操作的常用工具。

3.1 fopen:打開文件流

fopen 用于創建或打開文件,返回文件流指針(FILE*),是所有 C 庫文件操作的起點。

函數原型:
#include <stdio.h>FILE *fopen(const char *filename, const char *mode);
參數說明:
  • filename:文件路徑(絕對或相對路徑,如 "./test.txt""/tmp/log.txt")。
  • mode:打開模式,決定文件的讀寫權限和行為,常用模式如下:
模式含義說明適用場景
"r"只讀模式,文件必須存在,否則打開失敗。讀取已存在的文件
"w"只寫模式,文件不存在則創建,存在則清空原有內容。覆蓋寫入新內容
"a"追加模式,文件不存在則創建,寫入內容自動追加到文件末尾(不覆蓋原有內容)。日志記錄、持續追加數據
"r+"讀寫模式,文件必須存在,可讀寫但不清空內容。修改已存在的文件
"w+"讀寫模式,文件不存在則創建,存在則清空內容。新建或覆蓋文件并讀寫
"a+"讀寫模式,文件不存在則創建,寫入追加到末尾,讀取從開頭開始。追加數據同時需要讀取歷史內容

擴展模式:

  • 二進制模式:模式后加 b(如 "rb""wb+"),表示按字節讀寫(不轉換換行符),適用于圖片、視頻等二進制文件。
  • 文本模式:默認模式(不加 b),Windows 下會自動轉換 \n\r\n(Linux 無區別)。
返回值:
  • 成功:返回非 NULLFILE* 指針(后續操作基于此指針)。
  • 失敗:返回 NULL(需檢查!否則操作空指針會導致程序崩潰)。
示例:打開文件用于寫入
FILE *fp = fopen("test.txt", "w");  // 以只寫模式打開,不存在則創建
if (fp == NULL) {  // 必須檢查返回值perror("fopen failed");  // 輸出錯誤信息(如權限不足、路徑不存在)return 1;
}
// 文件操作...
fclose(fp);  // 操作完成后關閉

3.2 fclose:關閉文件流

fclose 用于關閉已打開的文件流,釋放資源并確保緩沖區數據寫入磁盤。

函數原型:
#include <stdio.h>int fclose(FILE *stream);
參數與返回值:
  • streamfopen 返回的文件流指針(FILE*)。
  • 返回值:成功返回 0;失敗返回 EOF(通常因磁盤錯誤或流已關閉)。
核心作用:
  1. 刷新用戶態緩沖區:將未寫入磁盤的數據通過底層系統調用刷盤(避免數據丟失)。
  2. 釋放資源:關閉底層文件描述符,釋放文件流占用的內存。
注意事項:
  • 必須調用:未關閉的文件流可能導致緩沖區數據丟失或文件描述符泄漏(系統允許打開的文件數有限)。
  • 檢查返回值:雖不常見,但 fclose 失敗可能意味著數據未完全寫入(如磁盤滿),需處理錯誤。
示例:關閉文件流
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) { perror("fopen failed"); return 1; }// 寫入數據...// 關閉文件流并檢查錯誤
if (fclose(fp) == EOF) {perror("fclose failed");  // 數據可能未完全寫入return 1;
}

3.3 寫入函數:fputc、fputs、fprintf

C 標準庫提供多種寫入函數,分別適用于單個字符、字符串和格式化數據的場景。

3.3.1 fputc:寫入單個字符
#include <stdio.h>// 向文件流寫入單個字符
int fputc(int character, FILE *stream);
  • 參數character 為待寫入字符(int 類型兼容 EOF);stream 為目標文件流。
  • 返回值:成功返回寫入的字符(轉換為 int);失敗返回 EOF
示例:
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) { perror("fopen failed"); return 1; }fputc('H', fp);  // 寫入 'H'
fputc('i', fp);  // 寫入 'i'
fputc('\n', fp); // 寫入換行符fclose(fp);  // 文件內容:Hi\n
3.3.2 fputs:寫入字符串
#include <stdio.h>// 向文件流寫入字符串(不自動添加換行符)
int fputs(const char *str, FILE *stream);
  • 參數str 為以 \0 結尾的字符串(\0 不寫入);stream 為目標文件流。
  • 返回值:成功返回非負值;失敗返回 EOF
優勢:

puts 更靈活(可指定輸出流),且不自動添加換行符,控制更精確。

示例:
FILE *fp = fopen("test.txt", "w");
if (fp == NULL) { perror("fopen failed"); return 1; }fputs("Hello, ", fp);   // 寫入 "Hello, "
fputs("World!\n", fp);  // 寫入 "World!\n"fclose(fp);  // 文件內容:Hello, World!
3.3.3 fprintf:格式化寫入
#include <stdio.h>// 按格式字符串向文件流寫入數據(類似 printf,但輸出到文件)
int fprintf(FILE *stream, const char *format, ...);
  • 參數stream 為目標文件流;format 為格式字符串(如 "%s %d %.2f");... 為可變參數(待寫入的數據)。
  • 返回值:成功返回寫入的字符數;失敗返回負值。
示例:寫入格式化數據
#include <stdio.h>int main() {FILE *fp = fopen("user_info.txt", "w");if (fp == NULL) { perror("fopen failed"); return 1; }char name[] = "張三";int age = 20;float score = 95.5;// 格式化寫入數據fprintf(fp, "姓名:%s,年齡:%d,分數:%.2f\n", name, age, score);fclose(fp);// 文件內容:姓名:張三,年齡:20,分數:95.50return 0;
}
說明:

fprintf 支持與 printf 相同的格式占位符(%s%d%f 等),可將多種類型的數據按指定格式寫入文件,是格式化輸出的常用工具。

3.4 讀取函數:fgetc、fgets、fscanf

C 標準庫提供多種讀取函數,分別適用于單個字符、行讀取和格式化數據的場景,需注意區分文件末尾與讀取錯誤。

3.4.1 fgetc:讀取單個字符
#include <stdio.h>// 從文件流讀取單個字符
int fgetc(FILE *stream);
  • 參數stream 為目標文件流指針。
  • 返回值
    • 成功:返回讀取的字符(轉換為 int 類型,范圍 0~255)。
    • 結束/失敗:返回 EOF(需通過 feof(stream) 判斷是否為文件末尾,ferror(stream) 判斷是否為錯誤)。
關鍵:區分“文件末尾”與“錯誤”
  • feof(stream):若流已到達文件末尾,返回非 0 值(真)。
  • ferror(stream):若流發生讀取錯誤,返回非 0 值(真)。
示例:循環讀取文件內容
#include <stdio.h>int main() {FILE *fp = fopen("test.txt", "r");if (fp == NULL) {perror("fopen failed");return 1;}int ch;  // 用 int 存儲,避免與 EOF 混淆(EOF 為 -1)while ((ch = fgetc(fp)) != EOF) {putchar(ch);  // 將讀取的字符輸出到屏幕}// 判斷結束原因if (feof(fp)) {printf("\n讀取完成:已到達文件末尾\n");} else if (ferror(fp)) {perror("讀取錯誤");}fclose(fp);return 0;
}
說明:

若文件內容為 Hello, World!,程序會將內容逐字符輸出到屏幕,結束時提示“已到達文件末尾”。

3.4.2 fgets:讀取一行字符串(安全版)
#include <stdio.h>// 從文件流讀取最多 num-1 個字符到緩沖區(自動添加 '\0')
char *fgets(char *str, int num, FILE *stream);
  • 參數
    • str:存儲讀取結果的緩沖區(需提前分配內存)。
    • num:最大讀取字符數(實際讀取 num-1 個,預留 '\0' 作為字符串結束標志)。
    • stream:目標文件流指針。
  • 返回值
    • 成功:返回 str(緩沖區指針)。
    • 結束/失敗:返回 NULL(若文件末尾前已讀取部分數據,str 仍有效;若錯誤,str 內容不確定)。
優勢:防止緩沖區溢出

fgets 明確限制讀取長度,避免了 gets(無長度限制)的安全隱患,是讀取字符串的首選函數。

示例:讀取文件內容(按行讀取)
#include <stdio.h>int main() {FILE *fp = fopen("test.txt", "r");if (fp == NULL) {perror("fopen failed");return 1;}char buf[100];  // 最多存儲 99 個字符 + '\0'while (fgets(buf, sizeof(buf), fp) != NULL) {printf("讀取內容:%s", buf);  // 包含換行符(若一行未超緩沖區)}fclose(fp);return 0;
}
說明:

若文件內容為多行文本,fgets 會逐行讀取,每次最多讀取 99 個字符(緩沖區大小 100),換行符會被包含在結果中。

3.4.3 fscanf:格式化讀取
#include <stdio.h>// 按格式字符串從文件流讀取數據(類似 scanf,但輸入來自文件)
int fscanf(FILE *stream, const char *format, ...);
  • 參數
    • stream 為目標文件流;
    • format 為格式字符串(如 "%s %d %f");
    • ... 為存儲結果的變量地址(需用 & 取地址,字符串數組除外)。
  • 返回值:成功匹配并賦值的參數個數;文件末尾或失敗返回 EOF
示例:讀取格式化數據

假設有文件 user.txt,內容為 張三 20 95.5,讀取代碼如下:

#include <stdio.h>int main() {FILE *fp = fopen("user.txt", "r");if (fp == NULL) {perror("fopen failed");return 1;}char name[20];int age;float score;// 按格式讀取數據int ret = fscanf(fp, "%s %d %f", name, &age, &score);if (ret == 3) {  // 成功匹配 3 個參數printf("姓名:%s,年齡:%d,分數:%.2f\n", name, age, score);// 輸出:姓名:張三,年齡:20,分數:95.50} else if (ret == EOF) {perror("讀取失敗");} else {printf("格式不匹配,成功讀取 %d 個參數\n", ret);}fclose(fp);return 0;
}
注意事項:
  • 格式字符串需與文件內容嚴格匹配(如空格、數據類型),否則可能讀取失敗。
  • 字符串 %s 遇空格/換行停止讀取,若需讀取含空格的字符串,需用 fgets 配合 sscanf 處理。

3.5 標準流:stdin、stdout、stderr

C 標準庫預定義了三個無需 fopen 即可直接使用的文件流,對應系統默認的輸入輸出設備,是程序與用戶交互的基礎。

標準流對應設備類型特性常用場景
stdin標準輸入(鍵盤)輸入流行緩沖:輸入數據需按回車后才提交給程序(可通過 fflush(stdin) 刷新)。讀取用戶輸入
stdout標準輸出(屏幕)輸出流行緩沖:輸出數據遇換行或緩沖區滿時才顯示(可通過 fflush(stdout) 強制刷新)。輸出正常結果
stderr標準錯誤(屏幕)錯誤流無緩沖:數據立即顯示,不受緩沖區影響。輸出錯誤信息、異常提示
示例:使用標準流
#include <stdio.h>
#include <string.h>int main() {// 1. 從 stdin 讀取用戶輸入char input[100];fprintf(stdout, "請輸入姓名:");  // 等價于 printf("請輸入姓名:")fflush(stdout);  // 強制刷新緩沖區(確保提示先顯示)if (fgets(input, sizeof(input), stdin) == NULL) {fprintf(stderr, "讀取輸入失敗!\n");  // 錯誤信息輸出到 stderrreturn 1;}// 去除輸入中的換行符(若存在)input[strcspn(input, "\n")] = '\0';// 2. 向 stdout 輸出結果fprintf(stdout, "你好,%s!\n", input);  // 等價于 printf("你好,%s!\n", input)// 3. 模擬錯誤輸出if (strlen(input) == 0) {fprintf(stderr, "錯誤:姓名不能為空!\n");  // 錯誤信息實時顯示}return 0;
}
說明:
  • printf(...) 本質是 fprintf(stdout, ...) 的宏定義。
  • fputs("消息", stdout) 等價于 puts("消息")(但 puts 會自動添加換行符)。
  • stderr 輸出的信息通常在終端中以紅色高亮顯示,便于區分正常輸出與錯誤。

四、文件 IO 核心流程與最佳實踐總結

核心流程

C 標準庫文件操作的完整流程可概括為:

打開文件(fopen) → 讀寫操作(fputc/fgets 等) → 關閉文件(fclose)

關鍵注意事項

  1. 檢查 fopen 返回值:始終判斷 FILE* 是否為 NULL,避免操作空指針導致程序崩潰。
  2. 及時調用 fclose:確保緩沖區數據刷盤,釋放文件描述符,避免資源泄漏(系統允許打開的文件數有限)。
  3. 優先使用安全函數:用 fgets 替代 gets(防止緩沖區溢出),用 snprintf 替代 sprintf(格式化輸出更安全)。
  4. 區分文本與二進制模式:讀寫文本文件用默認模式,讀寫圖片、視頻等二進制文件需加 b 標志(如 "rb""wb"),避免換行符轉換導致數據損壞。
  5. 處理讀取結束原因:用 feofferror 區分“文件末尾”和“讀取錯誤”,避免誤判。
  6. 格式化操作需匹配格式fscanf/fprintf 的格式字符串必須與數據類型嚴格匹配,否則易出現數據錯亂或讀取失敗。

總結

本文從文件系統底層的 inode 與 dentry 機制出發,詳細解析了文件元數據獲取函數 stat 的用法,隨后全面介紹了 C 標準庫中文件操作的核心函數:

  • fopen/fclose 負責文件流的打開與關閉,是所有操作的基礎;
  • fputc/fputs/fprintf 實現不同場景的寫入需求,支持字符、字符串和格式化數據;
  • fgetc/fgets/fscanf 實現靈活的讀取功能,需注意區分文件末尾與錯誤;
  • 標準流 stdin/stdout/stderr 簡化了程序與用戶的交互。

掌握這些函數的用法和底層原理,能高效、安全地處理文件 IO 操作,無論是日常應用開發還是系統工具編寫,都能打下堅實的基礎。

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

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

相關文章

WordPress Ads Pro Plugin本地文件包含漏洞(CVE-2025-4380)

免責聲明 本文檔所述漏洞詳情及復現方法僅限用于合法授權的安全研究和學術教育用途。任何個人或組織不得利用本文內容從事未經許可的滲透測試、網絡攻擊或其他違法行為。 前言:我們建立了一個更多,更全的知識庫。每日追蹤最新的安全漏洞,追中25HW情報。 更多詳情: http…

從爆紅到跑路:AI明星Manus為何僅用四個月就“拋棄”了中國?

目錄 前言 一、資本的“無形之手”&#xff1a;7500萬美元融資背后的“投名狀” 二、技術的雙重困境&#xff1a;算力封鎖與“應用層”的原罪 三、戰略的錯判&#xff1a;一場與中國市場的“雙向奔赴”失敗 四、事件的啟示&#xff1a;當“出海”變成“出走” &#x1f3a…

CCF-GESP 等級考試 2025年6月認證Python三級真題解析

1 單選題&#xff08;每題 2 分&#xff0c;共 30 分&#xff09;第1題 2025年4月19日在北京舉行了一場頗為矚目的人形機器人半程馬拉松賽。比賽期間&#xff0c;跑動著的機器人會利用 身上安裝的多個傳感器所反饋的數據來調整姿態、保持平衡等&#xff0c;那么這類傳感器類似于…

16.使用ResNet網絡進行Fashion-Mnist分類

16.1 ResNet網絡結構設計################################################################################################################ #ResNet ################################################################################################################…

C# 結構體 和 類 的區別

? 結構體&#xff08;struct&#xff09;是值類型&#xff08;Value Type&#xff09;和類&#xff08;class&#xff09;不同&#xff0c;結構體在賦值和傳參時是復制值本身&#xff0c;而不是引用地址。? 一、結構體的基本使用示例&#xff1a;using System;struct Point {…

MacBook Air M4 安裝 VMware Fusion Pro

VMware Fusion Pro已經對消費者免費了&#xff0c;在Windows系統上的安裝和使用教程比較多&#xff0c;Mac上竟然沒多少&#xff0c;還充斥著大量的廣告以及付費軟件&#xff0c;所以趁著今天要安裝虛擬機&#xff0c;記錄一下完整過程。 1&#xff0c;注冊博通賬號與登錄 首…

vue的優缺點

Vue的優點輕量級框架 Vue的核心庫僅關注視圖層&#xff0c;體積小巧&#xff08;約20KB&#xff09;&#xff0c;加載速度快&#xff0c;適合快速開發小型到中型項目。易于上手 文檔清晰且中文友好&#xff0c;API設計簡潔&#xff0c;學習曲線平緩。熟悉HTML、CSS和JavaScript…

閑庭信步使用圖像驗證平臺加速FPGA的開發:第七課——獲取RAW圖像

&#xff08;本系列只需要modelsim即可完成數字圖像的處理&#xff0c;每個工程都搭建了全自動化的仿真環境&#xff0c;只需要雙擊top_tb.bat文件就可以完成整個的仿真&#xff0c;大大降低了初學者的門檻&#xff01;&#xff01;&#xff01;&#xff01;如需要該系列的工程…

在前端項目中是如何解決跨域的

&#x1f4d8; 前端項目中跨域問題及解決方式詳解&#xff08;Vite 項目&#xff09;一、&#x1f310; 什么是跨域&#xff1f;跨域&#xff08;Cross-Origin&#xff09; 指的是在瀏覽器中&#xff0c;前端頁面與服務器之間的協議、域名或端口不一致而引發的安全限制。? 瀏覽…

代碼審計-Struts2漏洞分析

一、Struts2介紹 Struts2 是一個基于 MVC&#xff08;Model-View-Controller&#xff09; 設計模式的開源 Java Web 應用框架&#xff0c;由 Apache 軟件基金會維護。它是 Struts1 和 WebWork 框架的整合產物&#xff0c;以 WebWork 為核心&#xff0c;通過攔截器機制實現業務邏…

三、神經網絡——網絡優化方法

三、網絡優化方法 1.梯度下降算法梯段下降算法是一種尋找使損失函數最小化的方法&#xff0c;從數學上的角度來看&#xff0c;梯度的方向是函數增長速度最快的方向&#xff0c;那么梯度的反方向就是函數減少最快的方向&#xff0c;所以有WijnewWijold?η?E?WijW_{ij}^{new} …

HTML/JOSN復習總結

HTML 基礎 什么是 HTML? 1.HTML是一門語言&#xff0c;所有的網頁都是用HTML這門語言編寫出來的 2.HTML(HyperText Markup Language):超文本標記語言。 >超文本:超越了文本的限制&#xff0c;比普通文本更強大。除了文字信息&#xff0c;還可以定義圖片、音頻、視頻等內…

Golang中的內置類型

A. int B. string C. struct D. array 首先&#xff0c;內置類型是指不需要引入任何關于這些數據類型的包&#xff0c;就可以引用的數據類型。那么&#xff0c;內置類型主要包括基本類型&#xff0c;復合類型&#xff0c;控制并發&#xff0c;高級抽象&#xff0c;特殊類型。…

通過命名空間引用了 Application 類,php不會自動包含路徑文件嗎?

示例代碼&#xff1a;報錯提示找不到Application類 use mvc\core\Application;$app new Application(); // 定義路由 $app->get(/, HomeControllerindex); $app->get(/user, UserControllershow); $app->post(/user, UserControllercreate);// 運行應用 $app->run…

PlantUML 基礎使用技術文檔

目錄 摘要 1. 什么是 PlantUML 2. 安裝與環境配置 2.1 本地使用 2.2 在線使用 3. 基本語法 3.1 示例&#xff1a;系統架構圖 3.2 常用元素 4. 渲染方式 4.1 VSCode 4.2 在線渲染 4.3 生成圖片 5. 推薦實踐 6. 常見圖類型 7. 進階功能 8. 典型應用場景 摘要 Pl…

Android Notification 通過增加addAction 跳轉回Service重新執行邏輯

1.場景描述在App內升級過程中&#xff0c;apk下載過程中網絡波動導致連接超時&#xff0c;下載失敗后Service生命周期結束。前臺通知也被清除。2.解決思路在通知欄中增加重試按鈕重啟下載服務。3.代碼NotificationManager mNotificationManager (NotificationManager) getSy…

帶貨視頻評論的用戶洞察 科大訊飛AI算法賽 Datawhale AI夏令營

賽題 2025 iFLYTEK AI開發者大賽https://challenge.xfyun.cn/topic/info?typevideo-comment-insight 一、賽事背景 在電商直播爆發式增長的數字化浪潮下&#xff0c;短視頻平臺積累了海量帶貨視頻及用戶互動數據。這些數據不僅是消費者對商品體驗的直接反饋&#xff0c;更蘊…

JAVA生成PDF(itextpdf)

java生成PDF有多種方式&#xff0c;比如itextpdf、 Apache PDFBox、Flying Saucer (XHTMLRenderer)、 OpenPDF等。今天要介紹的是itextpdf&#xff0c;及在開發過程中處理的問題。1. 引入POM<!--PDF導出POM--><dependency><groupId>com.itextpdf</groupId…

[爬蟲知識] 深入理解多進程/多線程/協程的異步邏輯

相關爬蟲實戰案例&#xff1a;[爬蟲實戰] 多進程/多線程/協程-異步爬取豆瓣Top250 相關爬蟲專欄&#xff1a;JS逆向爬蟲實戰 爬蟲知識點合集 爬蟲實戰案例 逆向知識點合集 前言&#xff1a; 面對海量的目標數據&#xff0c;傳統單線程、同步的爬取方式往往效率低下&#x…

Oracle RAC 11.2.0.4 更新SYSASM和SYS密碼

前言 從技術角度看&#xff0c;SYSASM是Oracle 10g R2引入的ASM管理員角色&#xff0c;而SYS是數據庫實例的超級用戶&#xff0c;SYS賬戶無法管理ASM磁盤組。SYSASM權限是集群級別的&#xff0c;比如在添加磁盤組時&#xff0c;這個操作會影響所有節點&#xff1b;而SYS用戶的權…