Объединение двух файлов в двоичном формате - PullRequest
0 голосов
/ 21 декабря 2011

Я написал этот код для проверки объединения двух файлов:

 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 ]

3 голосов
/ 21 декабря 2011

*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 () вернуть количество успешно прочитанных или записанных элементов (т. е. не количество символов).Если произошла ошибка или достигнут конец файла, возвращаемое значение - это короткий счетчик элементов (или ноль).

2 голосов
/ 21 декабря 2011

Обратите внимание, что нет реальной причины загружать оба исходных файла в память одновременно.Кроме того, это потенциально очень неэффективно для памяти, поскольку вы действительно читаете все файлы, а затем все, что вы делаете, это снова записываете содержимое.

На мой взгляд, лучший алгоритм,было бы:

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 байтов.

Также обратите внимание, что, избавившись от необходимости загружать весь файл, вам также больше не нужно открывать каждый входной файл дополнительновремя просто искать до конца, чтобы вычислить размер файла.

1 голос
/ 21 декабря 2011

pa и pb не указывают на действительную память.

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

Запомните free(), когда больше не требуется.

Проверьте все возвращаемые значения из функций fopen(), fread(), fwrite() и т. Д.

...