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. How to pass QNetworkReply‘s data without copying it into memory
Forum Updated to NodeBB v4.3 + New Features

How to pass QNetworkReply‘s data without copying it into memory

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 4 Posters 614 Views 2 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.
  • C Creaperdown

    Hey, I have a QNetworkReply whose data is a rather big pdf file. I need to pass that data to a function, which is supposed to write it to a file on the local file system, but I want to avoid copying the data into memory.

    Is there a way for me to pass the backing file of the QNetworkReply and read from there?

    Thanks in advance

    sierdzioS Offline
    sierdzioS Offline
    sierdzio
    Moderators
    wrote on last edited by
    #2

    @Creaperdown by default, Qt is using implicit sharing (copy-on-write) so as long as you pass data as const without altering it, no copying will occur.

    Also, QNetworkReply is a subclass of QIODevice so you can use QDataStream to parse it or copy to file etc.

    (Z(:^

    C 1 Reply Last reply
    0
    • sierdzioS sierdzio

      @Creaperdown by default, Qt is using implicit sharing (copy-on-write) so as long as you pass data as const without altering it, no copying will occur.

      Also, QNetworkReply is a subclass of QIODevice so you can use QDataStream to parse it or copy to file etc.

      C Offline
      C Offline
      Creaperdown
      wrote on last edited by
      #3

      @sierdzio So I could use something like:

      void saveToFile(const QByteArray& data)
      {
          QFile file(…);
          file.open(…);
          file.write(data);
      }
      
      …
      const QByteArray data = myResponse.readAll();
      saveToFile(data);
      

      And it would not copy the data into memory, but write it directly to the file?

      1 Reply Last reply
      0
      • C Offline
        C Offline
        Creaperdown
        wrote on last edited by Creaperdown
        #4

        Or should I use something like:

        void copyToFile(QDataStream& data)
        {
            QFile file(…);
            file.open(…);
         
            QDataStream out(&file);
            out << data;
        }
        
        …
        QDataStream data(myResponse);
        copyToFile(data);
        
        JonBJ 1 Reply Last reply
        0
        • C Creaperdown

          Or should I use something like:

          void copyToFile(QDataStream& data)
          {
              QFile file(…);
              file.open(…);
           
              QDataStream out(&file);
              out << data;
          }
          
          …
          QDataStream data(myResponse);
          copyToFile(data);
          
          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by
          #5

          @Creaperdown
          If you use QDataStream you will not just be writing content bytes to the file, you will be adding extra information. And the file will only then be readable by another application using QDataStream. If you expect to use the file with other applications that is probably not what you want.

          Your first attempt with void saveToFile(const QByteArray& data) will write from the original QByteArray without doing any copying.

          C JonBJ 2 Replies Last reply
          0
          • JonBJ JonB

            @Creaperdown
            If you use QDataStream you will not just be writing content bytes to the file, you will be adding extra information. And the file will only then be readable by another application using QDataStream. If you expect to use the file with other applications that is probably not what you want.

            Your first attempt with void saveToFile(const QByteArray& data) will write from the original QByteArray without doing any copying.

            C Offline
            C Offline
            Creaperdown
            wrote on last edited by
            #6

            @JonB So the first way is the one I‘d need?

            jsulmJ 1 Reply Last reply
            0
            • JonBJ JonB

              @Creaperdown
              If you use QDataStream you will not just be writing content bytes to the file, you will be adding extra information. And the file will only then be readable by another application using QDataStream. If you expect to use the file with other applications that is probably not what you want.

              Your first attempt with void saveToFile(const QByteArray& data) will write from the original QByteArray without doing any copying.

              JonBJ Online
              JonBJ Online
              JonB
              wrote on last edited by
              #7

              @JonB said in How to pass QNetworkReply‘s data without copying it into memory:

              Your first attempt with void saveToFile(const QByteArray& data) will write from the original QByteArray without doing any copying.

              1 Reply Last reply
              0
              • C Creaperdown has marked this topic as solved on
              • C Creaperdown

                @JonB So the first way is the one I‘d need?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #8

                @Creaperdown If you pass "by reference" nothing is copied anyway in C++...

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                C 1 Reply Last reply
                1
                • jsulmJ jsulm

                  @Creaperdown If you pass "by reference" nothing is copied anyway in C++...

                  C Offline
                  C Offline
                  Creaperdown
                  wrote on last edited by
                  #9

                  @jsulm Yes but my fear was that it will be loaded into memory, if I use readAll to get a QByteArray

                  JonBJ 1 Reply Last reply
                  0
                  • C Creaperdown

                    @jsulm Yes but my fear was that it will be loaded into memory, if I use readAll to get a QByteArray

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote on last edited by JonB
                    #10

                    @Creaperdown
                    That will indeed happen. Let's be clear: you can avoid taking an extra copy in memory by using the stuff above, but you can't somehow get a network reply and never copy it into memory in the first place in order to write it to file.

                    If you mean: as it stands the code reads the whole response into memory and then writes it to file. You could reduce how much memory you use if you used QIODevice::read() to read chunks at a time and QFile::write() them as you go.

                    C 1 Reply Last reply
                    3
                    • JonBJ JonB

                      @Creaperdown
                      That will indeed happen. Let's be clear: you can avoid taking an extra copy in memory by using the stuff above, but you can't somehow get a network reply and never copy it into memory in the first place in order to write it to file.

                      If you mean: as it stands the code reads the whole response into memory and then writes it to file. You could reduce how much memory you use if you used QIODevice::read() to read chunks at a time and QFile::write() them as you go.

                      C Offline
                      C Offline
                      Creaperdown
                      wrote on last edited by
                      #11

                      @JonB I see, that's probably what I'll go for then. I hoped there might be a possibility to copy the data directly from the file that QNetworkReply is based on to a new file, but it seems like this is not possible

                      jsulmJ 1 Reply Last reply
                      0
                      • C Creaperdown

                        @JonB I see, that's probably what I'll go for then. I hoped there might be a possibility to copy the data directly from the file that QNetworkReply is based on to a new file, but it seems like this is not possible

                        jsulmJ Offline
                        jsulmJ Offline
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #12

                        @Creaperdown said in How to pass QNetworkReply‘s data without copying it into memory:

                        file that QNetworkReply

                        There is no file. The incoming data is put into a buffer from which you then read it. Ideally you simply connect a slot to https://doc.qt.io/qt-6/qiodevice.html#readyRead of your QNetworkReply and read the data every time this slot is called.

                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        2

                        • Login

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