Unsolved How would a QFileWriter class work out?
-
Over the last couple days, I've been making a FileWriter class. Essentially, working like this.
FileWriter fw; fw.Write("text.txt", *insert any QT object here*);
I think this would make a great addition to the QT library. Maybe not my code, just the concept in general. There's a lot of repetitive tasks and human error opportunities in writing directly to the disk. Aside from a couple quirks I'm working out creating directories, it's very possible. There are just a lot of hoops to jump through for such a basic thing. C++, tsk tsk.
-
@jamieyello
What is the question here? Is it how to serialize anyQObject
for writing (which I imagine is difficult/impossible)? -
-
@SGaist
You can serialize any arbitraryQObject
toQTextStream
? I would have expected them to be non-serializable (all those internal pointers etc.!)? -
No you can't because there's no way to generically save a data structure without some base plumbing. What you can do is implement the QTextStream and/or QDataStream operators for the classes you want to serialise.
-
@SGaist
OK, that's what I would have expected, thanks. So the point is the OP will need to write that text serialization himself, I think he was expecting it to be available in Qt "out-of-the-box". -
You can automate some stuff with introspection but it's still you the developer that should provide the correct way to serialise deserialise its classes.
-
Hi!
The following function I've tested with QList<QByteArray>'s and QList<QString>'s, and it reads/writes (both types in the same file as well). The caveat being it isn't creating the necessary folders yet. I did see a long list of data types QDataStream supports, which for the life of me I can't find anymore. I guess I would be talking about a simplified version of QDataStream.
// Writes given QT object to disk. template <typename T> // Declared and defined in the .h file to avoid undefined reference errors bool Write(QString name, T const & object, bool append = false) { if (!append) Delete(name); // custom function QFile file(name); QDataStream stream(&file); if (file.open(QIODevice::WriteOnly | QIODevice::Append)) { stream << object; } else { qDebug() << "FileWriter::Write (" + name + ") Error: " + file.errorString(); return false; } file.close(); return true; }
Reading the data, (from an old function I haven't made modular)
QString CMM::LoadFromFile(QString cmmFile) { Clear(); QFile qfile(cmmFile); if (!qfile.open(QIODevice::ReadOnly)) return "Could not open .cmm file (" + cmmFile + "), Error message; " + qfile.errorString(); QDataStream stream(&qfile); stream >> fileNames; stream >> data; // Everything below just makes sure the data is correct and not corrupted qDebug() << "fileNames.length() = " << fileNames.length(); qDebug() << "data.length() = " << data.length(); qfile.close(); if (fileNames.length() == 0) { return "Invalid .cmm, no content detected."; } QString integrityCheck = Validate(); if (integrityCheck != "") { return integrityCheck; } return ""; }
-
Except it won't work with QObject based class as they can't be copied.
By the way it's Qt, QT stands for Apple's QuickTime which I guess is not your target with this class.
[edit: fixed missing reference to Apple SGaist]
-
@SGaist said in How would a QFileWriter class work out?:
Except it won't work with QObject based class as they can't be copied.
By the way it's Qt, QT stands for QuickTime which I guess is not your target with this class.
My first post was misleading. Obviously not any Q object would work, but a good majority of the types of data you would want to write to the disk do. Ay data type compatible with QDataStream.
So I guess what I'm trying to say is that this probably could have been easier, that a single class could handle all of that, including folder creation.
-
I don't say it's not a good idea but it looks like some kind of logger rather than a real load and store mechanism.
Most applications that uses files to save their objects usually follow a strict format to store and load their document/internal state. There's no one solution fits all. On top of that, the version of QDataStream should be set when doing so to ensure backward/forward compatibility if it makes sense for your application.
-
Alright, I'm really not one to argue here. Worth mentioning that I'm actually using this function internally in an object to just streamline the process, though I can't comment on this being much of a logger.
I'm actually building a custom .zip format atm. The last little quirk I've got to work out is learning how to write the data without the encoding. If you're still curious, it's all for a mod manager for a certain game, and generally, the only kind of data I'm working with is entirely unrelated to the program itself.
That's a good tip, setting the version. I wouldn't have thought of that until I ran into problems.
-
It doesn't look like QDataStream has an option to disable the writing of metadata through << operators when using template objects. writeRawData() requires a length field, and I don't believe it's possible to recognize that with a template object. The simple workaround would be to make the template method private with some secondary overload methods that would accept all the different kinds of data I plan on working with and then detect the lengths of the files, but I feel like that would defeat the goal of what I'm going for here.
I could remove the metadata manually. Looking at the resulting files through a hex editor, it seems simple enough to spot. Not preferable, not very optimized, having to open and close the file twice.