首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言入門

C語言良好編程習慣進階(三):I/O錯誤處理、臨時檔案與目錄操作

     編輯:C 語言入門

前言

延續前兩篇,本文聚焦於輸入輸出錯誤檢查、臨時檔案安全、目錄操作選型、I/O效能優化、記憶體管理等進階實戰技巧,助你寫出更健壯、高效的C程式。

一、I/O錯誤即時檢查

原則:每次呼叫I/O函數(fread, fwrite, fprintf 等)後,立即檢查 ferror()。因同一檔案每次操作都會產生新的 ferror 值,延遲檢查會導致錯誤資訊丟失。

FILE *fp = fopen("data.bin", "wb");
if (!fp) return -1;
fwrite(buf, 1, len, fp);
if (ferror(fp)) { /* 立即處理錯誤 */ }
fclose(fp);

二、臨時檔案安全建立

使用臨時檔案(tmpfile(), mkstemp())時必須解決兩個核心問題:

  1. 檔名衝突:使用系統提供的唯一檔名生成機制(mkstemp 模板),避免手動拼接檔名。
  2. 權限保護:建立時設定 0600 權限(僅擁有者讀寫),防止其他使用者竊讀、刪除、修改。mkstemp 預設即如此。
char tmpl[] = "/tmp/myprog_XXXXXX";
int fd = mkstemp(tmpl);  // 原子建立,返回唯一檔案描述符
if (fd == -1) { /* 處理錯誤 */ }
// 使用 fd 進行讀寫...
close(fd);
unlink(tmpl);  // 關閉後自動刪除(若在close前unlink,檔案關閉時釋放空間)

三、目錄 vs 資料庫:儲存策略選型

何時使用目錄(檔案系統),何時上資料庫?考量五個維度:

維度適用目錄/檔案適用資料庫
資料量小型、離散資料大量結構化資料
資料類型屬性、配置、小型二進位物件關聯性強、頻繁查詢更新的記錄
讀寫比讀多寫少大量寫入/更新
搜尋需求簡單路徑查找複雜條件檢索、索引
標準存取POSIX APISQL/ODBC/JDBC

實踐建議:目錄存指標(檔名、路徑),大檔案存檔案系統,元資料存資料庫。

四、I/O效能優化:多執行緒與非阻塞

  • I/O本質緩慢(機械硬碟尋道、網路延遲),完善I/O模型(如epoll/kqueue/IOCP)可大幅提升吞吐。
  • 建議採用「專用I/O執行緒池」:少數執行緒專責阻塞式讀寫,主邏輯執行緒通過無鎖隊列傳遞請求/回調。
  • 注意:多執行緒無法突破硬體頻寬上限,僅能掩蓋延遲、提高併發利用率。

五、目錄操作細節

  • rmdir() 僅能刪除空目錄。非空目錄需遞歸刪除子項(ftw + unlink/rmdir)或使用系統命令 system("rm -rf")(注意注入風險)。
  • Windows DELTREE / Linux rm -rf 會強制刪除整棵目錄樹(含隱藏、唯讀檔案),慎用。
  • fnmerge() 組合完整路徑前,務必先驗證磁碟機與父目錄是否存在,避免建立失敗。

六、陣列與指標最佳實踐

  1. 下標從0開始,變數名小寫且語義化(如 user_count 而非 a)。
  2. C語言不檢查越界,編碼時必須人工確保邊界條件正確(i < N 而非 i <= N)。
  3. 釋放無用指標:free(ptr); ptr = NULL; 防止野指標與重複釋放。
  4. 優先使用陣列語法(a[i])而非指標算術(*(a+i)),雖微增指令數但大幅提升可讀性。
  5. 絕不解引用空指標,傳入指標的函數開頭必須斷言 assert(ptr != NULL)。
  6. 指標函數返回型別:返回地址,說明符通常為資料型別指標(如 int*),而非 int。
  7. 避免多級指標(***ptr),除非極少數演算法必要,否則嚴重降低可讀性。
  8. 複雜結構畫圖:鏈表、樹、圖等結構操作前,先繪製記憶體佈局圖,思路清晰再寫碼。

七、總結

良好的習慣不僅是規範,更是減少Bug、提升維護性的利器。將上述原則內化為肌肉記憶,你的C代碼將更安全、更專業。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved