Разделение файла на блоки по N-байт
Есть текстовый файл размера N байт. Его нужно разделить на блоки по M байт. Каждый отдельный блок является новым текстовым файлом, в котором будет записано M байт от исходного файла.
Проблема: на выходе я постоянно получаю пустой файл размером 0 байт. Использование других функций для чтения/записи файлов тоже ничего не дает. Во всех случаях получается пустой текстовый файл.
// Чтение файла с сообщением
FILE* messageFile;
fopen_s(&messageFile, "./Alice/message.txt", "rb");
if (messageFile == NULL)
{
printf("Не удается открыть файл.\n");
return 0;
}
// Вычисляем размер файла с сообщением
fseek(messageFile, 0, SEEK_END);
size_t fileSize = ftell(messageFile);
fseek(messageFile, 0, SEEK_SET);
// Количество целых байт на один блок сообщения
size_t bytesPerBlock = 7;
// Количество новых файлов (блоков)
size_t amountBlocks = fileSize / bytesPerBlock;
// Создание массива файлов
FILE *messageBlocks;
messageBlocks = (FILE *)malloc(amountBlocks * sizeof(FILE));
fopen_s(&messageBlocks[0], "./block.txt", "wb");
// Буфер для чтения из исходного файла
char *buffer;
buffer = (char *)malloc(bytesPerBlock * sizeof(char));
// Чтение некоторого кол-ва байт исходного файла в буфер
printf("Прочитано %zd символов\n", fread(buffer, sizeof(char), bytesPerBlock,
messageFile));
// Запись данных из буфера в новый файл (блок)
printf("Записано %zd символов", fwrite(buffer, sizeof(char), bytesPerBlock,
&messageBlocks[0]));
fclose(messageFile);
fclose(&messageBlocks[0]);
Ответы (2 шт):
Не будем о самом подходе (я бы так не делал), и без того у вас масса неприятностей, связанных с указателями.
FILE *messageBlocks;
messageBlocks = (FILE *)malloc(amountBlocks * sizeof(FILE));
fopen_s(&messageBlocks[0], "./block.txt", "wb");
Смотрите, у вас по сути создается массив элементов FILE, и функции вы передаете не адрес переменной типа FILE*, как положено, и как делаете выше для исходного файла, а адрес переменной типа FILE, что неверно!
Как минимум исправьте на
FILE **messageBlocks;
messageBlocks = (FILE **)malloc(amountBlocks * sizeof(FILE));
fopen_s(&messageBlocks[0], "./block.txt", "wb");
Точно так же вы неверно пишете — надо не
fwrite(buffer, sizeof(char), bytesPerBlock, &messageBlocks[0]));
а
fwrite(buffer, sizeof(char), bytesPerBlock, messageBlocks[0]));
Да и закрывать файл надо как fclose(messageBlocks[0]);...
Попробуйте изменить свой код, внеся указанные исправления. Кстати, вы совсем не обращаете внимания на предупреждения компилятора? Это вы напрасно...
Да, в C все эти приведения типов возле malloc не нужны. А вы действительно компилируете файл как С, а не С++, так как иначе он бы просто не скомпилировался...
Файлов может быть очень много, и все их открыть окажется невозможно. Вот вариант, когда открытых файлов только два.
#include <stdio.h>
#include <stdlib.h>
int main() {
// Чтение файла с сообщением
FILE* messageFile;
fopen_s(&messageFile, "message.txt", "rb");
if (messageFile == NULL) {
printf("Не удается открыть файл.\n");
return 0;
}
const size_t bytesPerBlock = 7;
char* buf = malloc(bytesPerBlock);
for (int i = 0;; ++i) {
char name[20];
snprintf(name, 20, "block%d.txt", i);
FILE* messageBlock;
fopen_s(&messageBlock, name, "wb");
if (messageBlock == NULL) break;
size_t readed = fread(buf, sizeof(char), bytesPerBlock, messageFile);
if (readed) fwrite(buf, sizeof(char), readed, messageBlock);
fclose(messageBlock);
if (readed != bytesPerBlock) break;
}
fclose(messageFile);
free(buf);
}
Ещё здесь последний файл не обязательно содержит полное количество байт - N может не делиться на M нацело.