Как мы можем разбить один 100-Гбайт файл на сто 1 ГБ файл?

Этот вопрос пришел на ум, когда я пытался решить проблему this.

У меня есть жесткий диск емкостью 120 ГБ, из которых 100 ГБ занят одним огромным файлом. Таким образом, 20 ГБ по-прежнему бесплатны.

Мой вопрос в том, как мы можем разделить этот огромный файл на более мелкие, скажем по 1 ГБ каждый? Я вижу, что если бы я имел свободное пространство на 100 ГБ, возможно, это было возможно с помощью простого алгоритма. Но, учитывая только 20 ГБ свободного места, мы можем записать до 20 1GB файлов. Я не знаю, как удалить содержимое из большего файла во время чтения из него.

Любое решение?

Кажется, я должен обрезать файл на 1 ГБ, как только я закончу писать один файл, но это сводится к этому заданию:

Можно ли обрезать часть файла? Как именно?

Я хотел бы увидеть алгоритм (или схему алгоритма), который работает на C или С++ (желательно Standard C и С++), , поэтому я могу узнать подробности нижнего уровня. Я не ищу волшебную функцию, script или команду, которая может выполнять эту работу.

Ответ 1

Для этого задания нет стандартной функции.

Для Linux вы можете использовать метод ftruncate, в то время как для Windows вы можете использовать _ chsize или SetEndOfFile. Простой #ifdef сделает его кросс-платформенным. Также читайте этот Q & A.

Ответ 2

В соответствии с этот вопрос (частично обрезая поток) вы должны иметь возможность использовать в системе, совместимой с POSIX, вызов int ftruncate(int fildes, off_t length), чтобы изменить размер существующего файла.

Современные реализации, вероятно, изменят размер файла "на месте" (хотя это не указано в документации). Единственная проблема заключается в том, что вам, возможно, придется выполнить дополнительную работу, чтобы гарантировать, что off_t является 64-разрядным типом (существуют положения в стандарте POSIX для 32-разрядных типов off_t).

Вы должны предпринять шаги для обработки условий ошибок, на случай, если они по какой-то причине не сработают, поскольку, очевидно, любой серьезный сбой может привести к потере вашего файла на 100 ГБ.

Pseudocode (предположим, и предпринять шаги для обеспечения того, чтобы все типы данных были достаточно большими, чтобы избежать переполнения):

open (string filename) // opens a file, returns a file descriptor
file_size (descriptor file) // returns the absolute size of the specified file
seek (descriptor file, position p) // moves the caret to specified absolute point
copy_to_new_file (descriptor file, string newname)
// creates file specified by newname, copies data from specified file descriptor
// into newfile until EOF is reached

set descriptor = open ("MyHugeFile")
set gigabyte = 2^30 // 1024 * 1024 * 1024 bytes

set filesize = file_size(descriptor)
set blocks = (filesize + gigabyte - 1) / gigabyte

loop (i = blocks; i > 0; --i)
    set truncpos = gigabyte * (i - 1)
    seek (descriptor, truncpos)
    copy_to_new_file (descriptor, "MyHugeFile" + i))
    ftruncate (descriptor, truncpos)

Очевидно, что некоторые из этих псевдокодов аналогичны функциям, найденным в стандартной библиотеке. В других случаях вам придется писать свои собственные.