コピーしたファイルが化けてしまった件

Clonezillaという、ディスクイメージをそのままバックアップ出来るソフトウェアがあります
私は重宝しているのですが、とかくファイルのサイズが大きくなります
親フォルダの中に4GBのファイルがいくつか作られるのですが、その中の一つが壊れてしまったようです

Clonezilla自身に、ファイルの整合性をチェックする機能があり、使えないと判断されてしまいました

どうな風に壊れたか見てみたい

コピー元のファイルがまだ残っていたので、Visual Studio 2015 を使って、差分をダンプするプログラムを書いてみました
差分さえ分かれば良いので、DOSプログラムです
なお、エラーチェックや戻り値の確認など、怪しい部分がありますがご容赦下さい

Visual Studio 2015 の使い方

スタートメニューのVisual studio 2015から、開発者コマンド プロンプト for VS2015 を実行する
(普段からVisual Studioとか使っておられる方から怒られそうだが…)
下記のようなコードを書いて、test.cという名前で保存する

#include <stdio.h>
int main(void) {
    printf("VS2015\n");
}

保存したフォルダに移動して、cl test.c と入力するとtest.exeが作成される

プログラム例

バイナリファイルの先頭8バイトだけ表示するようなプログラムは、下記のようになる

#include <stdio.h>
int main(void) {
    unsigned char buf[8];
    FILE *file;

    file = fopen("d:\\make\\test.dat", "rb");

    fseek(file, 0, SEEK_END);
    printf("%d Byte\n", ftell(file));
    fseek(file, 0, SEEK_SET);

    fread(&buf, sizeof(char), sizeof(buf), file);
    fclose(file);

    for(int i = 0; i < sizeof(buf); i++){
        printf("%02x", buf[i]);
        printf(" ");
    }
    return(0);
}

また、100バイト区切りで、全てのデータを表示する場合は下記のようになる

#include <stdio.h>
int main(void) {
    unsigned char buf[100];
    FILE *file;

    file = fopen("d:\\make\\test.dat", "rb");

    while(1){
        int rtn = fread(&buf, sizeof(char), sizeof(buf), file); // 1バイトx100
        printf("%d\n", rtn);
        for(int i = 0; i < rtn; i++){
            printf("%02x", buf[i]);
            printf(" ");
        }
        printf("\n");
        if(rtn < sizeof(buf)) break;
    }
    fclose(file);

    return(0);
}

目的としていた差分を表示できるように、下記のように書き直した

#include <stdio.h>
int main(void) {
    unsigned char buf1[100];
    unsigned char buf2[100];
    FILE *file1;
    FILE *file2;
    int loop = 0;
    int diff = 0;

    file1 = fopen("d:\\make\\test1.dat", "rb");
    file2 = fopen("d:\\make\\test2.dat", "rb");

    while(1){
        int rtn = fread(&buf1, sizeof(char), sizeof(buf1), file1);
        fread(&buf2, sizeof(char), sizeof(buf2), file2);
        for(int i = 0; i < rtn; i++){
            if(buf1[i] != buf2[i]){
                printf("pos=%d data1=%02x data2=%02x\n", loop * sizeof(buf1) + i + 1, buf1[i], buf2[i]);
                diff++;
            }
        }
        loop++;
        if(rtn < sizeof(buf1)) break;
    }
    fclose(file1);
    fclose(file2);
    printf("diff=%d\n", diff);

    return(0);
}

この結果、4GBのファイル(4,096,000,000 バイト)中、143,367か所の差異が見つかった
0.000035%だが、0%ではない以上このファイルは役に立たない
ちなみに化けたデータは、0e,2b,6a,05の繰り返しとなっていた
Windows上でコピーしただけなのにどうしてこのように化けてしまったのか?
やはり、robocopy.exe等を使うべきか?

この記事が気に入ったらサポートをしてみませんか?