Рекомендовать библиотеку С++ для разделения файла на куски и объединения его обратно?

У меня есть входной файл(ы), который может иметь размер до 25 ГБ. Тип файла может быть изображением, видео, текстом, двоичным файлом и т. д. Я хочу знать, есть ли у меня кросс-платформенная библиотека, которая обеспечивает способ разделения/объединения файлов.

Или если есть класс/функция в C++, которая предоставляет мне такую ​​​​утилиту.

Почему бы не использовать любую из обычных систем ввода-вывода C++? Прочитайте файл и запишите его в разные файлы для разделения; прочитайте выходные файлы и объедините их, чтобы присоединиться. Или позвоните в GNU coreutils splitи cat.
Посмотрите на исходный код пакета Debian splitи в нем.joincoreutils

Ответы (1)

Как говорит @Kodiologist, это не так уж сложно сделать из первых принципов:

Изменить: упростить код. К сожалению, дополнительная сложность, связанная с поддержкой любого типа потока, в этом контексте бесполезна.

#include <fstream>
#include <memory>
#include <sstream>
#include <vector>

const int size1MB = 1024 * 1024;

std::unique_ptr<std::ofstream> createChunkFile(std::vector<std::string>& vecFilenames) {
    std::stringstream filename;
    filename << "chunk" << (vecFilenames.size() + 1) << ".txt";
    vecFilenames.push_back(filename.str());
    return std::make_unique<std::ofstream>(filename.str(), std::ios::trunc);
}

void split(std::istream& inStream, int nMegaBytesPerChunk, std::vector<std::string>& vecFilenames) {

    std::unique_ptr<char[]> buffer(new char[size1MB]);
    int nCurrentMegaBytes = 0;

    std::unique_ptr<std::ostream> pOutStream = createChunkFile(vecFilenames);

    while (!inStream.eof()) {
        inStream.read(buffer.get(), size1MB);
        pOutStream->write(buffer.get(), inStream.gcount());
        ++nCurrentMegaBytes;
        if (nCurrentMegaBytes >= nMegaBytesPerChunk) {
            pOutStream = createChunkFile(vecFilenames);
            nCurrentMegaBytes = 0;
        }
    }

}

void join(std::vector<std::string>& vecFilenames, std::ostream& outStream) {
    for (int n = 0; n < vecFilenames.size(); ++n) {
        std::ifstream ifs(vecFilenames[n]);
        outStream << ifs.rdbuf();
    }
}

void createTestFile(const std::string& filename) {
    std::ofstream ofs(filename, std::ios::trunc);

    std::unique_ptr<char[]> buffer(new char[size1MB]);

    int i = 0;

    for (int n = 0; n < 1024; ++n) {
        for (int m = 0; m < size1MB; ++m) {
            buffer[m] = 'a' + (i++ % 26);
        }

        ofs.write(buffer.get(), size1MB);
    }
}

int main()
{

    // Create test file

    std::string filenameBefore = "before-big.txt";
    createTestFile(filenameBefore);

    // Split

    std::ifstream ifs(filenameBefore);
    std::vector<std::string> vecFilenames;

    split(ifs, 100, vecFilenames);

    // Join

    std::string filenameAfter = "after-big.txt";

    std::ofstream ofs(filenameAfter, std::ios::trunc);
    join(vecFilenames, ofs);

    return 0;
}

Это собирается для меня в Visual Studio 2015. Нет причин, по которым этого не должно быть ни в одном компиляторе C++11 (но я не могу обещать, что вам не придется вносить незначительные коррективы).

Вот быстрая проверка работоспособности, чтобы разделенный и объединенный файл был таким же, как и исходный.

сравнить файлы md5

Тип ошибки, которую я здесь проверяю, как раз и есть причина, по которой я предпочитаю полагаться на проверенный и проверенный код, но я не уверен coreutils, что его удобно взять и использовать в качестве библиотеки. Честно говоря, я бы, вероятно, просто выполнил двоичные файлы splitи joinкак дочерние процессы из моей основной программы.