Разбиение любых файлов на несколько частей - C (СИ)
Формулировка задачи:
Есть ли, какая-нибудь функция с которой можно разбивать любые файлы по битам?
Например, картинка размеров в 1 мегабайт, мне нужно ещё разбить на 5 частей, то есть, чтобы одна часть была размером в 200 килобайт
Решение задачи: «Разбиение любых файлов на несколько частей»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long file_size(const char* filename)
{
size_t len = 0;
FILE *file = fopen(filename, "r");
fseek(file, 0L, SEEK_END);
len = ftell(file);
fclose(file);
return len;
}
size_t number_length(size_t num)
{
size_t count = 1;
if (num < 10)
return 1;
do
{
count++;
}
while (num /= 10);
return num;
}
int split_file(const char* filename, size_t chunks_count)
{
FILE *file = NULL, *temp_file = NULL;
char *buf;
char *chunk_file_name = NULL;
size_t chunk_index = 0U;
size_t chunk_file_name_length = 0;
size_t readed_bytes;
size_t filename_length = strlen(filename);
chunk_file_name_length = filename_length + number_length(chunks_count) + 5;
chunk_file_name = (char*)calloc(chunk_file_name_length, sizeof(char));
long chunk_size = file_size(filename) / chunks_count;
buf = calloc(chunk_size, sizeof(char));
file = fopen(filename, "r");
if (!file)
{
return 1;
}
while (!feof(file) && !ferror(file))
{
strcpy(chunk_file_name, filename);
strcat(chunk_file_name, ".part%d");
sprintf(chunk_file_name, chunk_file_name, chunk_index);
chunk_index++;
readed_bytes = fread(buf, sizeof(char), chunk_size, file);
if (readed_bytes == 0)
{
break;
}
temp_file = fopen(chunk_file_name, "w");
if (!temp_file)
{
free(buf);
free(chunk_file_name);
fclose(file);
return 1;
}
fwrite(buf, sizeof(char), readed_bytes, temp_file);
if (fclose(temp_file))
{
free(buf);
free(chunk_file_name);
fclose(file);
return 1;
}
memset(chunk_file_name, 0, chunk_file_name_length);
}
free(buf);
free(chunk_file_name);
return fclose(file);
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
puts("Invalid parameters");
}
else
{
char *filename = argv[1];
size_t chunks_count = 0;
if (sscanf(argv[2], "%zu", &chunks_count) != 1)
{
fprintf(stderr, "Invalid argument %s\n", argv[2]);
return 0;
}
return split_file(filename, chunks_count);
}
}
Объяснение кода листинга программы
- В функции
mainпроверяется корректность ввода данных пользователем. Если пользователь вводит некорректные данные, выводится сообщение об ошибке и программа завершается. - В функции
split_fileсоздаются и открываются файлы для чтения исходного файла и записи разделенных частей. - В функции
split_fileфайл исходного файла открывается в режиме чтения (r). - В функции
split_fileфайлы для записи разделенных частей создаются с помощью функцииfopenс указанием имени файла и режима записи (w). - В функции
split_fileвыполняется чтение исходного файла и запись разделенных частей в созданные файлы. - В функции
split_fileпосле завершения чтения исходного файла и записи разделенных частей в файлы, файлы с разделенными частями закрываются. - В функции
split_fileпосле завершения работы с файлами, исходный файл закрывается. - В функции
number_lengthвыполняется определение длины числа, представленного в виде строки. - В функции
file_sizeопределяется размер файла. - В функции
mainвыполняется проверка корректности ввода данных пользователем. - В функции
mainопределяется количество частей, на которые необходимо разделить файл. - В функции
mainпередаются аргументы командной строки в функциюsplit_file. - В функции
mainвыполняется вызов функцииsplit_file. - В функции
mainвыводится сообщение об успешном выполнении программы. - В функции
mainобрабатывается ошибка, возникающая при попытке чтения некорректного аргумента. - В функции
mainпрограмма завершается. - В функции
split_fileиспользуется функцияcallocдля выделения памяти под буфер чтения исходного файла. - В функции
split_fileиспользуется функцияfreadдля чтения данных из исходного файла в буфер. - В функции
split_fileиспользуется функцияfwriteдля записи данных из буфера в файл с текущей частью. - В функции
split_fileиспользуется функцияfcloseдля закрытия файлов.