Нужно скопировать файл с одной дирректории в другую.
Написал программу, в которой есть два объекта типа FILE, с помощью fseek(fin, 0, SEEK_END) получаем размер, а чтение и запись происходят с помощью fread и fwrite.
Файл читаю блоками по 256 байт, вот код:
// Переходим в конец файла
fseek(fin, 0, SEEK_END);
// Размер файла
unsigned int m_file_size = ftell(fin);
rewind(fin);
// BLOCK_SIZE = 256 байт
for(unsigned int i = 0; i < m_file_size / BLOCK_SIZE; ++i) {
fread(buffer, sizeof(unsigned char), BLOCK_SIZE, fin);
fwrite(buffer, sizeof(unsigned char), BLOCK_SIZE, fout);
}
// Дальше считываю остаток файла теми же fread и fwrite
Собственно, программа работает корректно с небольшими файлами (пробовал копировать файл размером 1 Гб - скопировал нормально). Однако при копировании фала размером 2.5 Гб. - выходной файл получается больше по размеру, чем входной.
Сам думаю, что проблема как раз в fseek, fread и fwrite, так как они работают с интом, который больше 2.147 Гб. не вместит.
Вопрос такой: что нужно использовать вместо этих трех функций, чтобы программа корректно работала для больших файлов?
UPDATE 1
Код с открытием файла:
// File to read
FILE *fin;
// File to write
FILE *fout;
const int BLOCK_SIZE = 256;
unsigned char buffer[BLOCK_SIZE];
if(!(fin = fopen(file_from_path.toStdString().c_str(), "rb")) == NULL &&
!(fout = fopen(file_to_path.toStdString().c_str(), "wb")) == NULL) {
// The end of the file
fseek(fin, 0, SEEK_END);
// Get size of the file
unsigned int m_file_size = ftell(fin);
// Go to start
rewind(fin);
// Read and write by "BLOCK_SIZE" bytes
for(size_t i = 0; i < m_file_size / BLOCK_SIZE; ++i) {
// Read "BLOCK_SIZE" bytes to buffer
fread(buffer, sizeof(unsigned char), BLOCK_SIZE, fin);
// Write "BLOCK_SIZE" bytes
fwrite(buffer, sizeof(unsigned char), BLOCK_SIZE, fout);
}
}
Поскольку в стандарте работа идет с int
да long
, каковые в большинстве своем 32-битные, я бы использовал нестандартные функции операционной системы или соответствующие расширения компилятора.
Если это VC++, то можно использовать всяческие нестандартные расширения - функции типа _fseeki64
, _ftelli64
и иже с ними - например, см. тут.
Кстати, вот это
fread(buffer, sizeof(unsigned char), BLOCK_SIZE, fin);
fwrite(buffer, sizeof(unsigned char), BLOCK_SIZE, fout);
некорректно. С чего вы решили, что у вас размер кратен размеру буфера?
int readed = fread(buffer, sizeof(unsigned char), BLOCK_SIZE, fin);
fwrite(buffer, sizeof(unsigned char), readed, fout);
правильнее. Но по-хорошему, надо еще и возврат записи проверять.
Ага, вот причина большего размера: fseek/ftell
при некорректной работе возвращают -1, что у вас для вашего unsigned m_file_size
трансформируется в 4 Гигабайта. Результат понятен...
Вот работающий код. Правда, надо все равно проверять возврат всех функций...
// File to read
FILE *fin;
// File to write
FILE *fout;
const int BLOCK_SIZE = 256;
unsigned char buffer[BLOCK_SIZE];
if(!(fin = fopen("data.in", "rb")) == NULL &&
!(fout = fopen("data.out", "wb")) == NULL) {
// The end of the file
_fseeki64(fin, 0, SEEK_END);
// Get size of the file
long long m_file_size = _ftelli64(fin);
// Go to start
_fseeki64(fin, 0, SEEK_SET);
// Read and write by "BLOCK_SIZE" bytes
for(size_t i = 0; i <= m_file_size / BLOCK_SIZE; ++i) {
int readed = fread(buffer, sizeof(unsigned char), BLOCK_SIZE, fin);
fwrite(buffer, sizeof(unsigned char), readed, fout);
}
fclose(fin);
fclose(fout);
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Я разрабатываю приложение для аудиоустройства, работающего по стандарту usb audioОдной из задач является выбор формата воспроизведения: количество...
When I'm building a project in sublime text using command shift b i getting only 2 options and both of them are about building single fileTherefore main file can see none of my headers
Приветствую, господаПомогите пожалуйста с "почти" готовыми кодами, которые нужно довести до ума
Доброго времени сутокВ своем вопросе рассматриваю паттерны прокси и декоратор исключительно в контексте языка c++