Очень медленное создание образа диска (iso 9660) в C

В качестве забавного проекта я подумал, что напишу программу для создания iso-файлов. Насколько я могу сказать, это работает, но читает только 4 КБ каждые 30 секунд. Я использовал eject -x 11, чтобы замедлить мой привод cdrom до разумной скорости. Без этого привод работает на полной скорости и довольно быстро убивает процесс. Будем очень благодарны за любые предложения сделать это быстрее / лучше.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFFSIZE 4092

int main(int argc, char **argv)
{
    FILE *fp = fopen("/dev/cdrom", "r");
    FILE *file = fopen(strcat(argv[1], ".iso"), "w");

    printf("Copying...\n");

    while(!feof(fp))
    {
        char *line=(char *)malloc(sizeof(char) * BUFFSIZE);
        fgets(line, BUFFSIZE, fp);
        fprintf(file, "%s",line);

        free(line);
    }//end while

    fclose(fp);
    fclose(file);

    printf("Done!\n");

    return 0;
}//end main

5 ответов

fgets() обрабатывает текст и ориентирован на строки, и тратит время на поиск новых строк. Кроме того, это и fprintf() не справляться NUL байты, и могут быть очень запутаны ими. Вы хотите использовать бинарный IO, т.е. fread() а также fwrite(), Также нет необходимости постоянно free() и перераспределить ваш буфер.

Если вы хотите использовать примитивы Unix IO вместо оболочек C, вы можете использовать read() а также write() или же mmap() вместо.

  • Буферизованный ввод-вывод вряд ли уместен в этом сценарии, равно как и fgets, который сканирует ввод для новой строки. Посмотрите в Mmap.
  • Непрерывное удаление / перераспределение буфера замедляет работу.
  • Fprintf не подходит для записи двоичных данных. Это также медленно.

Прежде всего, я бы не пошел с форматированным вводом (fgets & текстовый режим), но с необработанным двоичным вводом (fopen с b флаг, fread а также fwrite для записи). Таким образом, stdio не нужно выполнять замены, необходимые для текстового режима (если это необходимо на вашей платформе), и у вас есть ряд операций чтения фиксированного размера, которые должны работать лучше, чем fgets' в ожидании \n,

Затем я избавился бы от этого динамического распределения памяти; непрерывное распределение / освобождение, вероятно, снижает производительность вашего приложения. Просто выделите один раз для всего статического буфера в стеке (например, 8192 байта) и используйте его все время.

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

Переместить malloc а также free вне петли.

Другие вопросы по тегам