Wie in Dateicontainer schreiben?
-
Sone schrieb:
Du willst also mehrere Dateien in eine einzige reinschaufeln? Das einfachste waere moeglicherweise einfach binaer hintereinander in eine Datei schreiben.
Und wie findest du den Anfang bzw. das Ende einer Datei oder eine bestimmte Datei? Ein bisschen weniger trivial ist das schon. Bloß mögliche Lösungswege gibt es viele, die zahle ich nicht alle auf, da müsste man eben Details kennen. ein sehr einfaches Format wäre tar, das gibt es auch schon in zahlreichen fertigen Implementierungen.
-
SeppJ schrieb:
Und wie findest du den Anfang bzw. das Ende einer Datei oder eine bestimmte Datei?
Echte Hacker riechen das!

-
SeppJ schrieb:
Sone schrieb:
Du willst also mehrere Dateien in eine einzige reinschaufeln? Das einfachste waere moeglicherweise einfach binaer hintereinander in eine Datei schreiben.
Und wie findest du den Anfang bzw. das Ende einer Datei oder eine bestimmte Datei?
Tabelle. Boost serialization. XML.

@Swordfish: schon wieder arbeitslos, oder wieso bist du so stinkig?
-
Sone schrieb:
@Swordfish: schon wieder arbeitslos, oder wieso bist du so stinkig?
... sprach der Schüler ohne Praktikum in den Ferien *lol*
-
Swordfish schrieb:
Sone schrieb:
@Swordfish: schon wieder arbeitslos, oder wieso bist du so stinkig?
... sprach der Schüler ohne Praktikum in den Ferien *lol*

Also ja?Mein Vorschlag (Die Strafe
fuer die "Initiative" des Fragestellers) :#include <iostream> #include <fstream> #include <sstream> #include <string> #include <unordered_map> #include <stdexcept> #include <vector> class BaseFileMixer { std::unordered_map<std::string, std::string> mData; public: std::unordered_map<std::string, std::string>::const_iterator getIterator() const { return mData.begin(); } std::unordered_map<std::string, std::string>::iterator getIterator() { return mData.begin(); } std::unordered_map<std::string, std::string>::const_iterator getEndIterator() const { return mData.end(); } bool add(std::string const& filename, std::string const& bytedata) { return mData.insert( std::make_pair(filename, bytedata) ).second; } virtual ~BaseFileMixer() {} }; class OFileMixer : public virtual BaseFileMixer { public: void add(std::string const& file) { std::ostringstream strstream; strstream << std::ifstream(file).rdbuf(); BaseFileMixer::add(file, strstream.str()); } bool writeTo(std::string const& file) { std::ofstream stream(file, std::ios::trunc); for(auto iter = getIterator();iter != getEndIterator(); ++iter) { if(iter != getIterator()) stream << ','; stream << iter->first << '|' << iter->second.length(); } stream << ';'; for(auto iter = getIterator();iter != getEndIterator(); ++iter) stream << iter->second; return stream; } }; class IFileMixer : public virtual BaseFileMixer { bool mIsOpen; public: IFileMixer(std::string const& file = std::string()) { if(file.empty()) return; open(file); } void open(std::string const& file) { std::ifstream stream(file); if(!stream) throw std::invalid_argument("IFileMixer::open Error with opening file " + file + "!"); std::vector<std::pair<std::string, size_t>> byteAmount; for(std::pair<std::string, size_t> temp; stream ;) { std::getline(stream, temp.first, '|'); stream >> temp.second; byteAmount.push_back(temp); if(stream.get() == ';') break; } if(!stream) throw std::logic_error("IFileMixer::open Error with parsing file " + file + "!"); for(auto pair : byteAmount) { std::pair<std::string, std::string> temp; temp.first = pair.first; while(pair.second--) temp.second += stream.get(); add( temp.first, temp.second ); } if(!stream) throw std::logic_error("IFileMixer::open Error with parsing file " + file + "!"); mIsOpen = true; } void extractTo(std::string const& dir = std::string()) { if( !mIsOpen ) throw std::logic_error("IFileMixer::extractTo called but the class didn't open a file yet!"); for(auto iter = getIterator();iter != getEndIterator();++iter) { std::ofstream stream( (( dir.length() )? dir + ((dir[dir.length() - 1] != '/')? "/" : "") : "") + iter->first, std::ios::trunc); if(!stream) throw std::logic_error("IFileMixer::extractTo stream for extraction of " + iter->first + " couldn't be opened!"); stream << iter->second; } } }; class FileMixer : public OFileMixer, public IFileMixer { public: FileMixer(std::string const& file = std::string()): IFileMixer(file) {} };
-
Sone schrieb:
"Initiative"
Ich fand die gar nicht so niedrig, die Strafe ist also viel zu hoch.
-
Keksschleuder schrieb:
Es weiß ja sicherlich jeder was eine zip oder eine rar Datei ist. Es gibt aber auch Software die ihre eigenen Container benutzt, wo dann alle möglichen Dateien drinn abgelegt werden.
Meine Frage lautet, wie erstellt man so einen Container (ohne Kompression)? Geht das überhaupt mit Standard C++ oder ist das Betriebssystem abhängig?Öh.
Dir ist hoffentlich klar dass ein Archiv mit einem "eigenen Format" einfach nur eine Datei ist, in die die Inhalte anderer Dateien reingeschrieben wurden. Halt irgendwie mit Inhaltsverzeichnis, damit das Archivprogramm auch weiss wie die Dateien alle heissen, wo sie anfangen etc.
Und wenn man das voraussetzt ist mMn. auch klar, dass das natürlich mit C++ umsetzbar ist. Wobei man vermutlich bei einigen Dingen plattformspezifische APIs wird verwenden müssen. z.B. kannst du mit ausschliesslich Standard C++ Funktionen nichtmal ein Verzeichnis enumerieren. Wenn du das für dein Archivprogramm brauchst (z.B. weil es Verzeichnisse mitsamt allen Dateien/Unterverzeichnissen aufnehmen können soll) -> plattformspezifische APIs.
Der "eigentlich" Archiv-Code kann aber vermutlich 100% plattformunabhängig gehalten werden.
-
hustbaer schrieb:
Wenn du das für dein Archivprogramm brauchst (z.B. weil es Verzeichnisse mitsamt allen Dateien/Unterverzeichnissen aufnehmen können soll) -> plattformspezifische APIs.
Ginge das nicht theoretisch mit Boost.Filesystem?
-
Sone schrieb:
hustbaer schrieb:
Wenn du das für dein Archivprogramm brauchst (z.B. weil es Verzeichnisse mitsamt allen Dateien/Unterverzeichnissen aufnehmen können soll) -> plattformspezifische APIs.
Ginge das nicht theoretisch mit Boost.Filesystem?
Und Boost.Filesystem funktioniert mit Magie?
-
Du legst die Dateien + Metadaten in eine Datei (Endung relativ egal).
-
Sone schrieb:
hustbaer schrieb:
Wenn du das für dein Archivprogramm brauchst (z.B. weil es Verzeichnisse mitsamt allen Dateien/Unterverzeichnissen aufnehmen können soll) -> plattformspezifische APIs.
Ginge das nicht theoretisch mit Boost.Filesystem?
Ja, Boost.Filesystem kann das. Und auch viele andere Libs (Qt, POCO, ...).
Wenn du den Satz der davor steht auch gelesen hast, sollte dir aber klar sein wie es gemeint war: man braucht plattformspezifischen Code um das zu erreichen, ODER eben Libraries die wiederum plattformspezifischen Code enthalten.
Die C++ Standard Library bietet auf jeden Fall nichts an mit dem man es machen könnte.
-
hustbaer schrieb:
man braucht plattformspezifischen Code um das zu erreichen, ODER eben Libraries die wiederum plattformspezifischen Code enthalten.

Dachte, du meinst, man muss selbst plattformspezifischen Code fabrizieren.
-
Sone schrieb:
hustbaer schrieb:
man braucht plattformspezifischen Code um das zu erreichen, ODER eben Libraries die wiederum plattformspezifischen Code enthalten.

Dachte, du meinst, man muss selbst plattformspezifischen Code fabrizieren.Naja ... er ... nö. So war es nicht gemeint. So eine Behauptung wäre auch reichlich doof bzw. gewagt.
Ich kann ja nicht alle Libraries kennen die es irgendwo gibt die irgendwas machen und auf mehr als einer Plattform lauffähig sind.Allerdings gibt es vermutlich auch keine Library die für sämtliche Plattformen verfügbar ist, wo auch eine halbwegs vollständige und standardkonforme C++ Implementierung verfügbar ist.
D.h. es wird Fälle geben, wo man mit Boost.Filesystem nicht weiter kommt, und auch mit Qt/POCO/... nicht. Die Standard C++ Library hätte man in diesen Fällen trotzdem, nur wie gesagt: die "kann" eben keine Verzeichnisse.
-
Na gut, ich versuche es einfacher auszudrücken. Im Grunde will ich nur mehrere Dateien in eine Datei zusammen fassen und auf diese natürlich auch zugreifen können. Keine kompriemierung, kein Passwortschutz, gar nichts.
Einfach nur z.B. text1.txt und text2.txt in container.con
Und dem Programm will ich dann "nur noch" sagen müssen öffne text2.txt in container.con
Wäre sowas mit Boost möglich?
€: Achja, es müsste unter Windows funktionieren.
-
Genau das hat man dir doch schon auf Seite 1 vorgekaut?!
-
Keksschleuder schrieb:
Na gut, ich versuche es einfacher auszudrücken. Im Grunde will ich nur (...)
Ja. OK. Was hält dich davon ab? Was ist deine Frage?