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 来恢复它们,对吗?这就是我的想法。

4

3 回答 3

3

*pa并且*pb需要指向应该读取文件内容的一些内存。

因此,使用 and 对这两个缓冲区执行 a并将malloc这些分配的缓冲区传递给:lengthA*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()返回成功读取或写入的项目数(即,不是字符数)。如果发生错误或到达文件结尾,则返回值是一个短项目计数(或零)。

于 2011-12-21T11:35:18.640 回答
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 字节。

另请注意,通过消除加载整个文件的需要,您不再需要额外的时间打开每个输入文件来寻找到最后以计算文件的大小。

于 2011-12-21T12:34:52.720 回答
1

pa并且pb没有指向有效的内存。

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

记住free()在不再需要时。

fopen()检查函数, fread(),fwrite()等的所有返回值。

于 2011-12-21T11:35:44.740 回答