У меня есть входной файл(ы), который может иметь размер до 25 ГБ. Тип файла может быть изображением, видео, текстом, двоичным файлом и т. д. Я хочу знать, есть ли у меня кросс-платформенная библиотека, которая обеспечивает способ разделения/объединения файлов.
Или если есть класс/функция в C++, которая предоставляет мне такую утилиту.
Как говорит @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 (но я не могу обещать, что вам не придется вносить незначительные коррективы).
Вот быстрая проверка работоспособности, чтобы разделенный и объединенный файл был таким же, как и исходный.
Тип ошибки, которую я здесь проверяю, как раз и есть причина, по которой я предпочитаю полагаться на проверенный и проверенный код, но я не уверен coreutils
, что его удобно взять и использовать в качестве библиотеки. Честно говоря, я бы, вероятно, просто выполнил двоичные файлы split
и join
как дочерние процессы из моей основной программы.
Кодиолог
split
иcat
.иваниван
split
и в нем.join
coreutils