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 write entire QVector to a binary file?

How to write entire QVector to a binary file?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qvectorbinary formatqdatastream
46 Posts 8 Posters 12.8k Views
  • 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 CJha
    17 Nov 2020, 10:43

    @J-Hilk That's a good point, but it's not the case for me as the data write and data read happens at different times. Also, SSD lifetime doesn't matter as these researchers have lots of funding and SSD is a cheap item for them. My job is to give them what they ask for, and if they ruin their SSD in 200 days that is up to them (of course I will tell them that it can ruin their SSD fast but that's all I can do).

    J Offline
    J Offline
    JonB
    wrote on 17 Nov 2020, 10:49 last edited by
    #31

    @CJha said in How to write entire QVector to a binary file?:

    Also, SSD lifetime doesn't matter as these researchers have lots of funding and SSD is a cheap item for them.

    LOL :)

    1 Reply Last reply
    1
    • C CJha
      17 Nov 2020, 10:43

      @J-Hilk That's a good point, but it's not the case for me as the data write and data read happens at different times. Also, SSD lifetime doesn't matter as these researchers have lots of funding and SSD is a cheap item for them. My job is to give them what they ask for, and if they ruin their SSD in 200 days that is up to them (of course I will tell them that it can ruin their SSD fast but that's all I can do).

      J Offline
      J Offline
      JonB
      wrote on 17 Nov 2020, 10:55 last edited by JonB
      #32

      @CJha
      BTW. When you have gotten it working with that file.write(), which is going to be as good as it gets. Since speed seems to be such an issue, and you're going to be doing ~1,000,000 points, and you goal is going to be to access the data array and write it out raw. Then my thought would be: why use a Qt QVector<> at all? For best efficiency/memory usage, would this be a case where simply creating a C++ array of doubles of sufficient size and storing into that directly/writing out to file would be simpler than wrapping it in QVector<> overheads: even if that is small, what's the point?

      And P.S.
      If you stick with QVector<>, do make sure you use QVector::resize/reserve(int size) appropriately early (once if possible), I think. What you do not want is to have the QVector keep reallocating/moving existing data as your million points keep arriving....

      C 1 Reply Last reply 17 Nov 2020, 11:43
      2
      • J JonB
        17 Nov 2020, 10:55

        @CJha
        BTW. When you have gotten it working with that file.write(), which is going to be as good as it gets. Since speed seems to be such an issue, and you're going to be doing ~1,000,000 points, and you goal is going to be to access the data array and write it out raw. Then my thought would be: why use a Qt QVector<> at all? For best efficiency/memory usage, would this be a case where simply creating a C++ array of doubles of sufficient size and storing into that directly/writing out to file would be simpler than wrapping it in QVector<> overheads: even if that is small, what's the point?

        And P.S.
        If you stick with QVector<>, do make sure you use QVector::resize/reserve(int size) appropriately early (once if possible), I think. What you do not want is to have the QVector keep reallocating/moving existing data as your million points keep arriving....

        C Offline
        C Offline
        CJha
        wrote on 17 Nov 2020, 11:43 last edited by
        #33

        @JonB I agree that a simple C++ array would be faster and easier as that is the format in which data is generated in the buffer from the acquisition device.

        However, if I write the data to a file in the same thread (in the same callback function where the data is deposited in the buffer from the acquisition device or in a different function), then since writing takes a long time it blocks the entire thread, this (once in a while) blocks the callback function which is called each time the required number of data samples is generated by the acquisition device resulting in an error.

        To solve this problem, I write data to a binary file in a different thread. Now, if I pass the address of the same buffer in which data is deposited then it defeats the purpose of having multiple threads as I am accessing the same buffer in which data is deposited from the acquisition device just from a different thread instead of the main one. To overcome this I write the incoming data from the acquisition device's buffer to a QVector<double> then send this vector over a Qt::QueuedConnection to my "Writer" thread and I write it there. I am not so good with C++ arrays and so I am not quite confident on how to achieve this without involving QVector in the process. If you have any idea on how can I simplify this process I will be very grateful :)

        J J 2 Replies Last reply 17 Nov 2020, 11:44
        0
        • C CJha
          17 Nov 2020, 11:43

          @JonB I agree that a simple C++ array would be faster and easier as that is the format in which data is generated in the buffer from the acquisition device.

          However, if I write the data to a file in the same thread (in the same callback function where the data is deposited in the buffer from the acquisition device or in a different function), then since writing takes a long time it blocks the entire thread, this (once in a while) blocks the callback function which is called each time the required number of data samples is generated by the acquisition device resulting in an error.

          To solve this problem, I write data to a binary file in a different thread. Now, if I pass the address of the same buffer in which data is deposited then it defeats the purpose of having multiple threads as I am accessing the same buffer in which data is deposited from the acquisition device just from a different thread instead of the main one. To overcome this I write the incoming data from the acquisition device's buffer to a QVector<double> then send this vector over a Qt::QueuedConnection to my "Writer" thread and I write it there. I am not so good with C++ arrays and so I am not quite confident on how to achieve this without involving QVector in the process. If you have any idea on how can I simplify this process I will be very grateful :)

          J Offline
          J Offline
          jsulm
          Lifetime Qt Champion
          wrote on 17 Nov 2020, 11:44 last edited by
          #34

          @CJha said in How to write entire QVector to a binary file?:

          then since writing takes a long time it blocks the entire thread

          You could do double-buffering with two arrays :-)

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

          C 1 Reply Last reply 17 Nov 2020, 12:40
          1
          • C CJha
            17 Nov 2020, 11:43

            @JonB I agree that a simple C++ array would be faster and easier as that is the format in which data is generated in the buffer from the acquisition device.

            However, if I write the data to a file in the same thread (in the same callback function where the data is deposited in the buffer from the acquisition device or in a different function), then since writing takes a long time it blocks the entire thread, this (once in a while) blocks the callback function which is called each time the required number of data samples is generated by the acquisition device resulting in an error.

            To solve this problem, I write data to a binary file in a different thread. Now, if I pass the address of the same buffer in which data is deposited then it defeats the purpose of having multiple threads as I am accessing the same buffer in which data is deposited from the acquisition device just from a different thread instead of the main one. To overcome this I write the incoming data from the acquisition device's buffer to a QVector<double> then send this vector over a Qt::QueuedConnection to my "Writer" thread and I write it there. I am not so good with C++ arrays and so I am not quite confident on how to achieve this without involving QVector in the process. If you have any idea on how can I simplify this process I will be very grateful :)

            J Offline
            J Offline
            JonB
            wrote on 17 Nov 2020, 11:54 last edited by
            #35

            @CJha
            My simple answer would be: mutexes. How that compares to queued signals I do not know; I am not suggesting mutexes, only answering the question.

            QVector<double> then send this vector over a Qt::QueuedConnection

            Wouldn't mind just seeing how you send it, do you use const QVector<> &?

            C 1 Reply Last reply 17 Nov 2020, 12:55
            0
            • J jsulm
              17 Nov 2020, 11:44

              @CJha said in How to write entire QVector to a binary file?:

              then since writing takes a long time it blocks the entire thread

              You could do double-buffering with two arrays :-)

              C Offline
              C Offline
              CJha
              wrote on 17 Nov 2020, 12:40 last edited by
              #36

              @jsulm I already use double buffering i.e. I assign twice the amount of memory for the buffer than needed. But I cannot use two separate buffers as these buffers are controlled by the C based specialized functions which are specific to the acquisition device. All I can do is assign the size of the memory to the buffer. The program flow is as follows:

              • Assign buffer size
              • Start acquisition
              • C based function puts data in the buffer and alerts my application through a callback function
              • I retrieve data from the buffer to a C array (I cannot retrieve directly to a vector as this step is also controlled by device-specific C function which only accepts a pointer to a C array)
              • Now I can do whatever I want with acquired data

              So, there is not much choice in terms of the buffer.

              Regarding the use of the C array that I use to get data out of the buffer, it is generated on the heap and deleted at the end of the callback function in which I get the data from the buffer.

              I could use two different vectors to store data and achieve so-called 'double buffering' from my application's point of view, and I have tried that. But in this case as well the thread is blocked for the time period of writing data to a file.

              1 Reply Last reply
              0
              • J JonB
                17 Nov 2020, 11:54

                @CJha
                My simple answer would be: mutexes. How that compares to queued signals I do not know; I am not suggesting mutexes, only answering the question.

                QVector<double> then send this vector over a Qt::QueuedConnection

                Wouldn't mind just seeing how you send it, do you use const QVector<> &?

                C Offline
                C Offline
                CJha
                wrote on 17 Nov 2020, 12:55 last edited by
                #37

                @JonB Yeah I could use mutexes, but I prefer Queued Connection as there is just one QVector to be sent to a different thread. I do not use const QVector<double>& because I want to depend on Qt's implicit sharing i.e. if the QVector<double> is changed while I am still using the previous QVector to write data in my binary file then it would not affect my "Writer" thread. If I would use const QVector<double>& then it would refer to the original QVector in the main thread and then I would have to use QMutex to protect read and write operations. This is my function in the Writer class which inherits QObject and is run in a different thread:

                void Writer::writeData(QVector<double> vec)
                {
                    ++sweepCount_; // Increament the count to keep track of number of times data vector is written
                
                    if(isBin_){ // If user selects file type as .bin
                        for(int ii = 0; ii < vec.length(); ++ii)
                            binOut_ << vec[ii]; // binOut_ is a QDataStrem, assigned to a file when the user clicks on Start button
                    }
                    else{ // if the user selects file type as .csv
                        if(vec.length() > 1){
                            outStream_ << vec[0];
                            for(int ii = 1; ii < vec.length(); ++ii)
                                outStream_ << seperator_ << vec[ii]; // seperator_ = ',' or ';' depending on QLocale
                            outStream_ << '\n';
                        }
                    }
                }
                
                J.HilkJ 1 Reply Last reply 18 Nov 2020, 06:20
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 17 Nov 2020, 18:25 last edited by
                  #38

                  Hi,

                  In what format do you get the data in the callback ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  C 1 Reply Last reply 18 Nov 2020, 08:20
                  0
                  • C CJha
                    17 Nov 2020, 12:55

                    @JonB Yeah I could use mutexes, but I prefer Queued Connection as there is just one QVector to be sent to a different thread. I do not use const QVector<double>& because I want to depend on Qt's implicit sharing i.e. if the QVector<double> is changed while I am still using the previous QVector to write data in my binary file then it would not affect my "Writer" thread. If I would use const QVector<double>& then it would refer to the original QVector in the main thread and then I would have to use QMutex to protect read and write operations. This is my function in the Writer class which inherits QObject and is run in a different thread:

                    void Writer::writeData(QVector<double> vec)
                    {
                        ++sweepCount_; // Increament the count to keep track of number of times data vector is written
                    
                        if(isBin_){ // If user selects file type as .bin
                            for(int ii = 0; ii < vec.length(); ++ii)
                                binOut_ << vec[ii]; // binOut_ is a QDataStrem, assigned to a file when the user clicks on Start button
                        }
                        else{ // if the user selects file type as .csv
                            if(vec.length() > 1){
                                outStream_ << vec[0];
                                for(int ii = 1; ii < vec.length(); ++ii)
                                    outStream_ << seperator_ << vec[ii]; // seperator_ = ',' or ';' depending on QLocale
                                outStream_ << '\n';
                            }
                        }
                    }
                    
                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on 18 Nov 2020, 06:20 last edited by J.Hilk
                    #39

                    @CJha said in How to write entire QVector to a binary file?:

                    I do not use const QVector<double>& because I want to depend on Qt's implicit sharing i.e. if the QVector<double> is changed while I am still using the previous QVector to write data in my binary file then it would not affect my "Writer" thread

                    So that you know, when passing your QVector through Qt::QueuedConnection - which is the default and correct one across threads - your QVector will be copied auto automatically, there will be no share until write. There will be a copy inside your thread


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    C 1 Reply Last reply 18 Nov 2020, 08:25
                    1
                    • SGaistS SGaist
                      17 Nov 2020, 18:25

                      Hi,

                      In what format do you get the data in the callback ?

                      C Offline
                      C Offline
                      CJha
                      wrote on 18 Nov 2020, 08:20 last edited by
                      #40

                      @SGaist Hi, It is double. The data is placed in a C Array from where I retrieve it.

                      1 Reply Last reply
                      0
                      • J.HilkJ J.Hilk
                        18 Nov 2020, 06:20

                        @CJha said in How to write entire QVector to a binary file?:

                        I do not use const QVector<double>& because I want to depend on Qt's implicit sharing i.e. if the QVector<double> is changed while I am still using the previous QVector to write data in my binary file then it would not affect my "Writer" thread

                        So that you know, when passing your QVector through Qt::QueuedConnection - which is the default and correct one across threads - your QVector will be copied auto automatically, there will be no share until write. There will be a copy inside your thread

                        C Offline
                        C Offline
                        CJha
                        wrote on 18 Nov 2020, 08:25 last edited by
                        #41

                        @J-Hilk Thanks, one thing which I am not sure about: What would happen if I use const QVector<double>& instead of QVector<double>, will it still copy the data if the connection type is Qt:QueuedConnection or will it just copy the reference for the vector?

                        KroMignonK 1 Reply Last reply 18 Nov 2020, 08:33
                        0
                        • C CJha
                          18 Nov 2020, 08:25

                          @J-Hilk Thanks, one thing which I am not sure about: What would happen if I use const QVector<double>& instead of QVector<double>, will it still copy the data if the connection type is Qt:QueuedConnection or will it just copy the reference for the vector?

                          KroMignonK Offline
                          KroMignonK Offline
                          KroMignon
                          wrote on 18 Nov 2020, 08:33 last edited by KroMignon
                          #42

                          @CJha said in How to write entire QVector to a binary file?:

                          will it still copy the data if the connection type is Qt:QueuedConnection or will it just copy the reference for the vector?

                          In short: Yes they will be copied.
                          For more details take a look at this => https://www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/

                          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                          C 1 Reply Last reply 18 Nov 2020, 08:35
                          3
                          • KroMignonK KroMignon
                            18 Nov 2020, 08:33

                            @CJha said in How to write entire QVector to a binary file?:

                            will it still copy the data if the connection type is Qt:QueuedConnection or will it just copy the reference for the vector?

                            In short: Yes they will be copied.
                            For more details take a look at this => https://www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/

                            C Offline
                            C Offline
                            CJha
                            wrote on 18 Nov 2020, 08:35 last edited by
                            #43

                            @KroMignon Thanks :)

                            J 1 Reply Last reply 18 Nov 2020, 09:29
                            0
                            • C CJha
                              18 Nov 2020, 08:35

                              @KroMignon Thanks :)

                              J Offline
                              J Offline
                              JonB
                              wrote on 18 Nov 2020, 09:29 last edited by
                              #44

                              @CJha
                              According to @KroMignon's link

                              The conclusion from the above results is that we should pass arguments to signals and slots by const reference and not by value. This advice is true for both direct and queued connections. Even if the sender of the signal and the receiver of the slot are in different threads, we should still pass arguments by const reference.

                              If you have both signal & slot declared with QVector<double> vec and you change both to have const QVector<double>&, you reduce 3 copies to 1.

                              Having said that: I do get lost as to what gets copied, aren't we only talking about the QVector structure and not the data it references??

                              C 1 Reply Last reply 18 Nov 2020, 13:05
                              0
                              • J JonB
                                18 Nov 2020, 09:29

                                @CJha
                                According to @KroMignon's link

                                The conclusion from the above results is that we should pass arguments to signals and slots by const reference and not by value. This advice is true for both direct and queued connections. Even if the sender of the signal and the receiver of the slot are in different threads, we should still pass arguments by const reference.

                                If you have both signal & slot declared with QVector<double> vec and you change both to have const QVector<double>&, you reduce 3 copies to 1.

                                Having said that: I do get lost as to what gets copied, aren't we only talking about the QVector structure and not the data it references??

                                C Offline
                                C Offline
                                CJha
                                wrote on 18 Nov 2020, 13:05 last edited by
                                #45

                                @JonB If it's a copy then I assume it is always going to be the data because the structure is not that significant in terms of memory usage, but I am not sure about it either.

                                J 1 Reply Last reply 27 Nov 2020, 14:34
                                0
                                • C CJha
                                  18 Nov 2020, 13:05

                                  @JonB If it's a copy then I assume it is always going to be the data because the structure is not that significant in terms of memory usage, but I am not sure about it either.

                                  J Offline
                                  J Offline
                                  jsulm
                                  Lifetime Qt Champion
                                  wrote on 27 Nov 2020, 14:34 last edited by
                                  #46

                                  @CJha said in How to write entire QVector to a binary file?:

                                  If it's a copy then I assume it is always going to be the data

                                  No, because Qt containers use copy-on-write. See https://doc.qt.io/qt-5/implicit-sharing.html

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

                                  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