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 any QObject for writing (which I imagine is difficult/impossible)?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    What you described makes me think of QFile with QTextStream.

    Isn't it ?



  • @SGaist
    You can serialize any arbitrary QObject to QTextStream? I would have expected them to be non-serializable (all those internal pointers etc.!)?


  • Lifetime Qt Champion

    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".


  • Lifetime Qt Champion

    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 "";
    }
    

  • Lifetime Qt Champion

    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.


  • Lifetime Qt Champion

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.