Сохранение файла изображения в буфер (GIF, JPEG и т. Д.). - PullRequest
0 голосов
/ 08 августа 2011

Я пытаюсь загрузить файл изображения в буфер, чтобы отправить его через гнездо. Проблема, которую я имею в том, что программа создает буфер с допустимым размером, но не копирует весь файл в буфер. Мой код выглядит следующим образом

//imgload.cpp
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

int main(int argc,char *argv){

    FILE *f = NULL;
    char filename[80];
    char *buffer = NULL;
    long file_bytes = 0;
    char c = '\0';
    int i = 0;

    printf("-Enter a file to open:");
    gets(filename);

    f = fopen(filename,"rb");
    if (f == NULL){
        printf("\nError opening file.\n");
    }else{
        fseek(f,0,SEEK_END);
        file_bytes = ftell(f);
        fseek(f,0,SEEK_SET);

        buffer = new char[file_bytes+10];

    }

    if (buffer != NULL){
        printf("-%d + 10 bytes allocated\n",file_bytes);
    }else{
        printf("-Could not allocate memory\n");
        // Call exit?.
    }

    while (c != EOF){
        c = fgetc(f);
        buffer[i] = c;
        i++;
    }

    c = '\0';                   
    buffer[i-1] = '\0';     // helps remove randome characters in buffer when copying is finished..
    i = 0;      

    printf("buffer size is now: %d\n",strlen(buffer));



    //release buffer to os and cleanup....




    return 0;
}

> вывод

c:\Users\Desktop>imgload
-Enter a file to open:img.gif
-3491 + 10 bytes allocated
buffer size is now: 9


c:\Users\Desktop>imgload
-Enter a file to open:img2.gif
-1261 + 10 bytes allocated
buffer size is now: 7

Из выходных данных я вижу, что он выделяет правильный размер для каждого изображения 3491 и 1261 байт (я дважды проверил размеры файлов через окна и размеры, которые были выделены правильно), но размеры буфера после предположительно копирования составляют 9 и 7. длинные байты. Почему он не копирует все данные?

Ответы [ 3 ]

6 голосов
/ 08 августа 2011

Вы не правы.Изображение - это двоичные данные, ни строковые данные.Итак, есть две ошибки:

1) Вы не можете проверить конец файла с константой EOF.Потому что EOF часто определяется как 0xFF и является действительным байтом в двоичном файле.Поэтому используйте функцию feof(), чтобы проверить конец файла.Или также вы можете проверить текущую позицию в файле с максимально возможным (вы получили это раньше с ftell()).

2) Поскольку файл является двоичным, он может содержать \0 в середине.Поэтому вы не можете использовать строковую функцию для работы с такими данными.

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

PS И я хочу сказать, что у вашей программы будут проблемы с действительно большими файлами.Кто знает, может быть, вы будете пытаться работать с ними.Если «да», переписать функции ftell / fseek в их int64 (long long int) эквиваленты.Также вам нужно исправить счетчик массива.Еще одна хорошая идея - читать файлы по блокам.Чтение за байтом значительно медленнее.

4 голосов
/ 08 августа 2011

Все это не нужно и фактически не имеет смысла:

c = '\0';                   
buffer[i-1] = '\0';
i = 0;

printf("buffer size is now: %d\n",strlen(buffer));

Не используйте strlen для двоичных данных . strlen останавливается на первом NUL (\0) байте. Двоичный файл может содержать много таких байтов, поэтому NUL нельзя использовать.

-3491 + 10 bytes allocated /* There are 3491 bytes in the file. */
buffer size is now: 9 /* The first byte with the value 0. */

В заключение отбросьте эту часть . У вас уже есть размер файла.

1 голос
/ 08 августа 2011

Вы читаете двоичный файл как текстовый файл. Вы не можете проверить EOF, поскольку это может быть где угодно в двоичном файле.

...