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

C 語言檔案操作函數完整實作指南

     編輯:關於C語言

前言

檔案操作是 C 語言系統程式設計的基石。本文將從零開始,完整實作一套跨平台的檔案操作函式庫,涵蓋開啟、讀寫、定位、關閉等核心功能,並處理錯誤碼、資源洩漏等工程級細節。

標頭檔設計:file_ops.h

#ifndef FILE_OPS_H
#define FILE_OPS_H

#include 
#include 

/* 檔案模式旗標 */
typedef enum {
    FILE_READ   = 0x01,  // 唯讀
    FILE_WRITE  = 0x02,  // 唯寫(截斷)
    FILE_APPEND = 0x04,  // 附加
    FILE_BINARY = 0x08   // 二進位模式
} FileMode;

/* 檔案控制結構(不透明指標) */
typedef struct FileHandle FileHandle;

/* 開啟檔案 */
FileHandle* file_open(const char* path, FileMode mode);

/* 關閉檔案 */
int file_close(FileHandle* handle);

/* 讀取資料 */
size_t file_read(FileHandle* handle, void* buffer, size_t size);

/* 寫入資料 */
size_t file_write(FileHandle* handle, const void* buffer, size_t size);

/* 取得檔案大小 */
long file_size(FileHandle* handle);

/* 設定讀寫位置 */
int file_seek(FileHandle* handle, long offset, int whence);

/* 取得目前位置 */
long file_tell(FileHandle* handle);

/* 取得最後錯誤訊息 */
const char* file_strerror(int errnum);

#endif

核心實作:file_ops.c

#include "file_ops.h"
#include 
#include 
#include 

struct FileHandle {
    FILE* fp;
    char* path;
    FileMode mode;
};

static const char* mode_to_stdio(FileMode mode) {
    static char buf[4];
    char* p = buf;
    if (mode & FILE_READ) *p++ = 'r';
    if (mode & FILE_WRITE) *p++ = 'w';
    if (mode & FILE_APPEND) *p++ = 'a';
    if (mode & FILE_BINARY) *p++ = 'b';
    *p = '\0';
    return buf;
}

FileHandle* file_open(const char* path, FileMode mode) {
    if (!path) return NULL;
    FileHandle* h = (FileHandle*)malloc(sizeof(FileHandle));
    if (!h) return NULL;
    h->fp = fopen(path, mode_to_stdio(mode));
    if (!h->fp) { free(h); return NULL; }
    h->path = strdup(path);
    h->mode = mode;
    return h;
}

int file_close(FileHandle* handle) {
    if (!handle) return -1;
    int ret = 0;
    if (handle->fp) ret = fclose(handle->fp);
    free(handle->path);
    free(handle);
    return ret;
}

size_t file_read(FileHandle* handle, void* buffer, size_t size) {
    if (!handle || !handle->fp || !buffer) return 0;
    return fread(buffer, 1, size, handle->fp);
}

size_t file_write(FileHandle* handle, const void* buffer, size_t size) {
    if (!handle || !handle->fp || !buffer) return 0;
    return fwrite(buffer, 1, size, handle->fp);
}

long file_size(FileHandle* handle) {
    if (!handle || !handle->fp) return -1;
    long cur = ftell(handle->fp);
    fseek(handle->fp, 0, SEEK_END);
    long sz = ftell(handle->fp);
    fseek(handle->fp, cur, SEEK_SET);
    return sz;
}

int file_seek(FileHandle* handle, long offset, int whence) {
    if (!handle || !handle->fp) return -1;
    return fseek(handle->fp, offset, whence);
}

long file_tell(FileHandle* handle) {
    if (!handle || !handle->fp) return -1;
    return ftell(handle->fp);
}

const char* file_strerror(int errnum) {
    return strerror(errnum);
}

使用範例

#include "file_ops.h"
#include 

int main() {
    FileHandle* f = file_open("demo.txt", FILE_WRITE | FILE_BINARY);
    if (!f) { perror("open"); return 1; }
    const char* msg = "Hello, File Ops!\n";
    file_write(f, msg, strlen(msg));
    file_close(f);

    f = file_open("demo.txt", FILE_READ | FILE_BINARY);
    if (!f) { perror("open"); return 1; }
    char buf[128];
    size_t n = file_read(f, buf, sizeof(buf)-1);
    buf[n] = '\0';
    printf("Read: %s", buf);
    file_close(f);
    return 0;
}

進階主題:錯誤處理與資源管理

  • 所有函式回傳錯誤碼或 NULL,呼叫端必須檢查。
  • 使用 RAII 風格的巨集或 C11 __attribute__((cleanup)) 自動關閉檔案。
  • 大檔案支援:Windows 使用 _fseeki64/_ftelli64,Linux 使用 fseeko/ftello。
  • 執行緒安全:單一 FileHandle 非執行緒安全,多執行緒需自行加鎖。

總結

封裝標準 C 庫的檔案操作,不僅能統一跨平台介面,更能在專案中強制統一錯誤處理與資源釋放規範。建議將此模組納入團隊基礎設施庫,並配合靜態分析工具檢查資源洩漏。

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