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 587 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 Offline
    C Offline
    Creaperdown
    wrote on last edited by Creaperdown
    #1

    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 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 Offline
      JonBJ Offline
      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
      • 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 Offline
              JonBJ Offline
              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 Offline
                  JonBJ Offline
                  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 Offline
                        JonBJ Offline
                        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