2011-12-21 117 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字节。

另外请注意,通过取消加载整个文件的需要,您不再需要打开每个输入文件一个额外的时间,只是为了计算文件的大小而寻求最后的结果。