C言語

【C言語】第7章第12回:巨大ファイルの分割と結合

巨大なファイルを効率よく扱うためのスキルは、データ処理やファイル管理において重要です。本記事では、C言語で巨大ファイルを分割・結合する方法について学びます。

0. 記事の概要

この記事を読むメリット

  • 効率的なデータ処理:巨大なファイルを扱うスキルが身につきます。
  • プロジェクトへの応用:大規模データを効率的に管理する方法を習得できます。
  • 応用力の向上:データ分割と統合の技術を応用できます。

この記事で学べること

  • 巨大ファイルを分割する方法
  • 分割されたファイルを結合する方法
  • エラー処理を含む実践的なプログラム例

活用のイメージ

巨大なログファイルやデータベースファイルを効率的に処理する際に、この技術が役立ちます。

1. 巨大ファイルを分割する

1.1 分割の概要

巨大ファイルを分割することで、以下のようなメリットがあります。

  • ファイルの転送時間を短縮できる
  • ストレージ管理が容易になる
  • 処理の並列化が可能になる

1.2 プログラムコード

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

#define CHUNK_SIZE 1024 // 分割サイズ(1KB)

void splitFile(const char *filename) {
    FILE *input = fopen(filename, "rb");
    if (input == NULL) {
        perror("Error opening file");
        return;
    }

    char buffer[CHUNK_SIZE];
    int part = 0;
    size_t bytesRead;

    while ((bytesRead = fread(buffer, 1, CHUNK_SIZE, input)) > 0) {
        char outputFilename[50];
        snprintf(outputFilename, sizeof(outputFilename), "part_%03d.bin", part++);
        FILE *output = fopen(outputFilename, "wb");
        if (output == NULL) {
            perror("Error creating part file");
            fclose(input);
            return;
        }
        fwrite(buffer, 1, bytesRead, output);
        fclose(output);
        printf("Created %s\n", outputFilename);
    }

    fclose(input);
    printf("File split into %d parts.\n", part);
}
動作解説
  1. 入力ファイルを開く:fopen()を使用して、読み取りモードでファイルを開きます。
  2. データを読み取る:fread()を使用して、一定サイズのデータをバッファに読み取ります。
  3. 部分ファイルを作成:fopen()で新しいファイルを作成し、fwrite()でデータを書き込みます。
  4. ファイルを閉じる:入力ファイルと部分ファイルを適切に閉じます。

2. 分割されたファイルを結合する

2.1 結合の概要

分割されたファイルを結合することで、元の巨大ファイルを再構築できます。以下にプログラム例を示します。

2.2 プログラムコード

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

void mergeFiles(const char *outputFilename, int numParts) {
    FILE *output = fopen(outputFilename, "wb");
    if (output == NULL) {
        perror("Error creating output file");
        return;
    }

    char buffer[1024];
    for (int i = 0; i < numParts; i++) {
        char inputFilename[50];
        snprintf(inputFilename, sizeof(inputFilename), "part_%03d.bin", i);
        FILE *input = fopen(inputFilename, "rb");
        if (input == NULL) {
            perror("Error opening part file");
            fclose(output);
            return;
        }

        size_t bytesRead;
        while ((bytesRead = fread(buffer, 1, sizeof(buffer), input)) > 0) {
            fwrite(buffer, 1, bytesRead, output);
        }
        fclose(input);
        printf("Merged %s\n", inputFilename);
    }

    fclose(output);
    printf("Files merged into %s\n", outputFilename);
}
動作解説
  1. 出力ファイルを作成:fopen()を使用して、書き込みモードでファイルを作成します。
  2. 部分ファイルを開く:fopen()で順番に部分ファイルを開きます。
  3. データのコピー:fread()fwrite()を使用してデータを結合します。
  4. ファイルのクローズ:出力ファイルと部分ファイルを適切に閉じます。

3. 練習問題

以下の課題に挑戦して、巨大ファイルの分割と結合スキルを向上させましょう。

  1. 分割サイズを指定できるように、splitFile関数を改良してください。
  2. 結合する部分ファイルの範囲を指定して、mergeFiles関数を改良してください。
  3. 分割されたファイルの整合性をチェックするプログラムを作成してください。

4. 練習問題の解答と解説

問1の解答

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

void splitFileWithSize(const char *filename, size_t chunkSize) {
    FILE *input = fopen(filename, "rb");
    if (input == NULL) {
        perror("Error opening file");
        return;
    }

    char buffer[1024];
    int part = 0;
    size_t bytesRead;

    while ((bytesRead = fread(buffer, 1, chunkSize, input)) > 0) {
        char outputFilename[50];
        snprintf(outputFilename, sizeof(outputFilename), "part_%03d.bin", part++);
        FILE *output = fopen(outputFilename, "wb");
        if (output == NULL) {
            perror("Error creating part file");
            fclose(input);
            return;
        }
        fwrite(buffer, 1, bytesRead, output);
        fclose(output);
        printf("Created %s\n", outputFilename);
    }

    fclose(input);
    printf("File split into %d parts with chunk size %zu bytes.\n", part, chunkSize);
}

このプログラムでは、ユーザーが指定した分割サイズに応じてファイルを分割します。

5. まとめ

本記事では、巨大ファイルを分割・結合する方法について学びました。これらのスキルを応用することで、大規模なデータを効率的に管理できます。次回は、さらに高度なデータ操作技術について学びます。