二進位檔案 I/O


使用二進位模式開啟檔案,在寫入或讀取檔案時不會發生字元轉換,數值在記憶體中的位元是如何,寫入檔案時就是如何,而讀入時也是相同。

要單純地以二進位方式讀取檔案,可以使用 fread 函式,在讀寫時是使用位元組為單位:

size_t fread( void* buffer, size_t size, size_t count, FILE* stream );

buffer 參數為讀入的資料所要存放的地方,size 是指讀入的位元組長度,count 是讀入的筆數。

以二進位方式讀取時,要判斷檔案是否到尾端,可以使用 feof 函式:

while(!feof(fp)) {
    ....
}

下面這個程式可以讀入任意檔案,每次讀入一個位元組,並將讀入的資料以 16 進位數顯示:

#include <stdio.h> 
#include <stdlib.h>

int main(int argc, char* argv[]) {
    FILE *fp = fopen(argv[1], "rb");
    if(!fp) { 
        perror("無法讀取檔案"); 
        return EXIT_FAILURE; 
    } 

    unsigned char ch; 
    int count = 0; 
    while(!feof(fp)) { 
        fread(&ch, sizeof(char), 1, fp);
        printf("%2X ", ch);
        count++; 
        if(count > 16) {  // 換行 
            putchar('\n');
            count = 0; 
        } 
    } 
    putchar('\n');

    fclose(fp);

    return 0; 
} 

執行結果:

23 69 6E 63 6C 75 64 65 20 3C 73 74 64 69 6F 2E 68 
3E 20  A 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  A 69 
6E 74 20 6D 61 69 6E 28 69 6E 74 20 61 72 67 63 2C 
20 63 68 61 72 2A 20 61 72 67 76 5B 5D 29 20 7B  A 
20 20 20 20 69 66 28 61 72 67 63 20 21 3D 20 32 29
略...

如果要寫入檔案,可以使用 fwrite

size_t fwrite( const void* buffer, size_t size, size_t count, FILE* stream );

下面這個程式可以讓你將任意的檔案複製至另一個指定的名稱:

#include <stdio.h> 
#include <stdlib.h>

int main(int argc, char* argv[]) {  
    FILE *src = fopen(argv[1], "rb"); 
    FILE *dest = fopen(argv[2], "wb"); 

    if(!src) { 
        perror("來源檔案開啟失敗"); 
        return EXIT_FAILURE; 
    } 

    if(!dest) { 
        perror("目標檔案建立失敗"); 
        return EXIT_FAILURE; 
    } 

    unsigned char ch; 
    while(!feof(src)) { 
        fread(&ch, sizeof(char), 1, src);
        if(!feof(src)) { 
            fwrite(&ch, sizeof(char), 1, dest);
        }
    } 

    fclose(src); 
    fclose(dest); 

    return 0; 
}

下面這個程式示範如何將陣列資料寫入檔案,然後再將之讀出:

#include <stdio.h> 
#include <stdlib.h>

int writeInts(int* arr, int len) {
    FILE *fp = fopen("temp", "wb");
    if(!fp) { 
        perror("無法讀取檔案"); 
        return EXIT_FAILURE; 
    } 
    fwrite(arr, sizeof(int) * len, 1, fp); 
    fclose(fp);
}

int readInts(int* arr, int len) {
    FILE *fp = fopen("temp", "rb"); 
    if(!fp) { 
        perror("無法讀取檔案"); 
        return EXIT_FAILURE; 
    } 

    fread(arr, sizeof(int) * len, 1, fp); 
    fclose(fp); 
}

int main(int argc, char* argv[]) {
    FILE *fp = fopen("temp", "wb");
    if(!fp) { 
        perror("無法讀取檔案"); 
        return EXIT_FAILURE; 
    } 

    const int len = 5;
    int arr[] = {1, 2, 3, 4, 5}; 

    writeInts(arr, len);
    readInts(arr, len);

    for(int i = 0; i < 5; i++) {
        printf("%d ", arr[i]); 
    }
    putchar('\n');

    return 0; 
}