Ich habe eine oder mehrere Eingabedateien, die eine Größe von bis zu 25 GB haben können. Der Dateityp kann ein Bild, ein Video, ein Text, eine Binärdatei usw. sein. Ich möchte wissen, ob es eine plattformübergreifende Bibliothek gibt, die eine Möglichkeit bietet, Dateien zu teilen/zu verbinden.
Oder ob es eine Klasse/Funktion in C++ gibt, die mir diese Art von Dienstprogramm bietet.
Wie @Kodiologist sagt, ist dies von Grund auf nicht allzu schwer:
Bearbeiten: Code vereinfachen. Leider ist die zusätzliche Komplexität durch die Möglichkeit, jeden Stream-Typ zu unterstützen, in diesem Zusammenhang nicht hilfreich.
#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;
}
Dies wird für mich in Visual Studio 2015 erstellt. Kein Grund, warum es nicht in jedem C++ 11-Compiler enthalten sein sollte (aber ich kann nicht versprechen, dass Sie keine kleineren Anpassungen vornehmen müssen).
Hier ist eine schnelle Plausibilitätsprüfung, ob die geteilte und verbundene Datei mit dem Original identisch ist
Die Art von Fehler, nach der ich hier suche, ist genau der Grund, warum ich mich lieber auf erprobten und getesteten Code verlassen würde, aber ich bin nicht überzeugt, dass coreutils
es bequem ist, ihn als Bibliothek zu greifen und zu verwenden. Um ehrlich zu sein, würde ich wahrscheinlich nur die Binärdateien split
und join
als untergeordnete Prozesse in meinem Hauptprogramm ausführen.
Kodiologe
split
undcat
.ivwan
split
undjoin
in Debianscoreutils
Paket an