Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Serializing a QFile
Forum Updated to NodeBB v4.3 + New Features

Serializing a QFile

Scheduled Pinned Locked Moved General and Desktop
7 Posts 4 Posters 3.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    talmage
    wrote on last edited by
    #1

    I'm looking for a natural way to read and write QFile objects from a QIODevice. I think this is a serialization problem. I don't think it can be done. Who can prove me wrong? (Please! :-))

    I'm writing a QIODevice wrapper for a protocol that transports files reliably via IP multicast. When the protocol engine receives a file, it informs the QIODevice. The QIODevice can raise the readyRead() signal. I'd like to be able to read a QFile from this QIODevice. For example, if the new file is "/tmp/foo.txt", I should be able to read QFile("/tmp/foo.txt") from this QIODevice.

    Similarly, I should be able to write QFile objects into the QIODevice so that the protocol engine can transmit them.

    Is this possible with Qt 4.x? I don't believe it is. I don't believe that QFile is serializable.

    The best solution so far is to read and write file names from the QIODevice. I can wrap the QFile ctor around one line read from the QIODevice, where a "line" is the name of a file. I can write file names into the QIODevice and have it make the protocol engine transmit the file.

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      Hi,

      By "serializing", do you mean "encoding for transmission via the protocol"? In my mind, a file's data is an array of bytes, so I see it as "serialized" by definition. Please correct me if I'm wrong.

      Ok, for now I'll assume that you meant "encoding for transmission", and also assume that your custom QIODevice provides the encoding/decoding functions.

      You could set it up like this, where you implement the encoding/decoding in CustomDevice::writeData() and CustomDevice::readData()

      @
      // Receive a file
      CustomDevice customDevice;
      customDevice.open(QIODevice::ReadOnly);

      QFile receivedFile( customDevice.getFileName() );
      receivedFile.open(QIODevice::WriteOnly);

      receivedFile.write(customDevice.readAll());

      // Send a file
      QFile fileToSend("file.txt");
      receivedFile.open(QIODevice::ReadOnly);

      CustomDevice customDevice;
      customDevice.setFileName( fileToSend.fileName() );
      customDevice.open(QIODevice::WriteOnly);

      customDevice.write(fileToSend.readAll());
      @

      Some other info that might be useful:

      • A QFile IS a QIODevice
      • Qt has a built-in data serializer, designed to work closely with QIODevices. They have examples on how it interacts with QFiles: http://qt-project.org/doc/qt-4.8/qdatastream.html

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • T Offline
        T Offline
        talmage
        wrote on last edited by
        #3

        Thanks for the detailed response, JKSH.

        What I propose to do is read a QFile object, not the contents of a file, from my QIODevice.

        The protocol sends files. Let's say it sends foo.txt. It notifies the receiver app when all of foo.txt has been received. As a response to that notification, I can want to create an unopened QFile("foo.txt") and enqueue it the QIODevice's read buffer. When the receiver app responds to the readyRead() signal, it can read the QIODevice and deserialize the bytes into QFile("foo.txt"). The QFile never goes out onto the network.

        I still don't see a way to serialize QFile objects. QIODevice doesn't have a method for reading or writing QObjects. There may be no way to do what I want.

        1 Reply Last reply
        0
        • JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by
          #4

          Ah, I think I understand your intentions better now. So you want to serialize the object that manages the file, not the file data itself?

          I'm not sure if that's possible, or recommended... After all, a QFile is a QObject, and QObjects are designed to be uncopyable; serializing+transmitting an object -- even if it's on the same machine -- is a fancy way of making a copy.

          In any case, deserializing any object involves constructing a new object. What do you wish to achieve, that can't be done by simply constructing a new QFile from the received file's path? (e.g. the last paragraph of your original post)

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          1 Reply Last reply
          0
          • C Offline
            C Offline
            ChrisW67
            wrote on last edited by
            #5

            I think the only transferable properties that the QFile has are the file name, its open flags, current open/closed state, and seek position (a QString, QFlags<OpenModeFlag>, bool, and qint64). The first is meaningful at the receiving end only if the same file exists at the same location on that machine. The other parameters could be used to put a receiver local QFile wrapping that file in a similar state assuming the file is identical to the sending system's file... otherwise all bets are off.

            Since you are talking about serialising an unopened QFile then all you need send is the QFile::filename(). There are obvious methods to send a QString.

            1 Reply Last reply
            0
            • T Offline
              T Offline
              talmage
              wrote on last edited by
              #6

              Thanks, JKSH and ChrisW67, for your advice. I solved the problem as I predicted, with file names instead of QFiles. To send a file, write the name of the file terminated with a newline into my QIODevice. On the receiving side, use the QIODevice's readLine() to read the name of the least recently received file.

              The work in progress is part of a "suite of mobile ad hoc networking applications for mobile phones":https://github.com/MobileEmergencyCommunicationsProject/manetsuite. Look at "qnormfiletransport.h":https://github.com/MobileEmergencyCommunicationsProject/manetsuite/blob/master/qnormtransport/qnormfiletransport.h and "qnormfiletransport.cpp":https://github.com/MobileEmergencyCommunicationsProject/manetsuite/blob/master/qnormtransport/qnormfiletransport.cpp.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #7

                Sounds brittle to me.

                I'd look into using QDataStream instead. First send the file name as a string, and then the contents as a QByteArray. That way, you will have no problems with issues like the file itself containing newlines too...

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved