2011-12-21 47 views
0

我寫了這個代碼來測試兩個文件合併:梳理兩個文件的二進制格式

long getFileSize(char *filename) 
{ 
    FILE* fp=fopen(filename,"rb"); 
    fseek(fp,0,SEEK_END); 
    long size=ftell(fp); 
    fclose(fp); 
    return size; 
} 



long lengthA = getFileSize(argv[1]); 
    long lengthB = getFileSize(argv[2]); 
    printf("sizeof %s is:%d\n",argv[1],lengthA); 
    printf("sizeof %s is %d\n",argv[2],lengthB); 

    void *pa; 
    void *pb; 
    FILE* fp=fopen(argv[1],"rb"); 
    fread(pa,1,lengthA,fp); 
    fclose(fp); 
    FILE* fpn=fopen(argv[2],"rb"); 
    fread(pb,1,lengthB,fpn); 
    fclose(fpn); 
    printf("pointerA is:%p;pointerB is:%p\n",pa,pb); 

    FILE *ff=fopen("test.pack","wb"); 
    fwrite(pa,1,lengthA,ff); 
    fwrite(pb,1,lengthB,ff); 
    fclose(ff); 

    long lengthFinal = getFileSize("test.pack"); 

    printf("Final size:%i\n",lengthFinal); 

,但是我不知道如果數據等於從getFileSize返回值,控制檯打印清楚地說什麼不對的地方,但我不能弄明白:

sizeof a.zip is:465235 
sizeof b.zip is 107814 
pointerA is:0x80484ec;pointerB is:0x804aff4 
Final size:255270 

,因爲我知道每個文件的長度,然後我就可以用FSEEK向右恢復呢?這就是我在想的想法。

回答

3

*pa*pb需要指向一些內存應該讀取的文件內容。

所以,做這兩個緩存一malloclengthA*sizeof(char)lengthB*sizeof(char),並通過這些分配的緩衝區fread

pa = malloc(lengthA*sizeof(char)); 
pb = malloc(lengthB*sizeof(char)); 
... 
fread(pa,sizeof(char),lengthA,fp); 
... 
fread(pb,sizeof(char),lengthB,fpn); 

此外,實際讀取的項目fread返回數字。也檢查這個!從man fread

摘錄:

的fread()的fwrite()返回的項目數成功地讀取或寫入(即,而不是字符數)。如果發生錯誤或達到文件結尾,則返回值是短項目計數(或零)。

1

papb沒有指向有效內存。

char* pa = malloc(lengthA * sizeof(char)); 
char* pb = malloc(lengthB * sizeof(char)); 

當不再需要時請記住free()

檢查從功能fopen()fread()fwrite()所有的返回值等

2

注意,有沒有真正的理由兩個源文件加載到內存中一次。另外,這樣做可能會非常耗費內存,因爲你真的在讀取所有的文件,然後你只需要再次寫出內容。

更好的算法,在我看來,應該是:

let C = a reasonable buffer size, say 128 KB 
let B = a static buffer of C bytes 
let R = the output file, opened for binary write 
for each input file F: 
    open F for binary read 
    repeat 
    let N be the number of bytes read, up to a maximum of C 
    if N > 0 
     write N first bytes of B into R 
    until N = 0 
    close F 
close R 

這與需要動態分配緩衝區摒棄,你可以只是做char C[B]並有#define B (128 << 10)

上面假設從沒有更多字節傳遞的文件中讀取返回0字節。

另外請注意,通過取消加載整個文件的需要,您不再需要打開每個輸入文件一個額外的時間,只是爲了計算文件的大小而尋求最後的結果。