我写了这段代码来测试结合两个文件:
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来恢复它们吗?这就是我在想的想法。
答案 0 :(得分:3)
*pa
和*pb
需要指向应该读取文件内容的内存。
因此,对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()返回成功读取或写入的项目数(即不是字符数)。如果发生错误或达到文件结尾,则返回值为短项目计数(或零)。
答案 1 :(得分: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字节。
另请注意,通过取消加载整个文件的需要,还不再需要额外打开每个输入文件,只是为了计算文件的目的而寻找到最后大小
答案 2 :(得分:1)
pa
和pb
未指向有效内存。
char* pa = malloc(lengthA * sizeof(char));
char* pb = malloc(lengthB * sizeof(char));
在不再需要时请记住free()
。
检查函数fopen()
,fread()
,fwrite()
等的所有返回值。