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. [SOLVED] Best way of reading bytes (with specific length) from QDataStream to QByteArray
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Best way of reading bytes (with specific length) from QDataStream to QByteArray

Scheduled Pinned Locked Moved General and Desktop
11 Posts 3 Posters 25.7k 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.
  • C Offline
    C Offline
    Code_ReaQtor
    wrote on 3 May 2013, 10:35 last edited by
    #1

    Greetings!

    I am using QDatastream to read bytes of specific length and saving it into a QByteArray. Right now I am using the following code:
    @QDataStream input(...);
    QByteArray buffer;
    int length = ...;
    ...
    quint8 byte;
    for(int i=0; i<length; ++i) {
    input >> byte;
    buffer.append(byte);
    }@

    The code is working but I am looking for a more optimized way since I think this is very slow especially when length is too big. I came across QDataStream::readRawData() and QDataStream::readBytes() but I don't know how to implement them since a QByteArray is '\0'-terminated and char* is not. Thanks!

    Please visit my open-source projects at https://github.com/Code-ReaQtor.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jeroentjehome
      wrote on 3 May 2013, 10:42 last edited by
      #2

      Hi,
      The QDateSteam is most likely set to a QIODevice? You should be able to use the readyRead() function of the QIODevice when new data is ready to be read. Or in the handling slot check the amount of bytes ready to read, then when all is in, read all available data with the int readRawData ( char * s, int len ) making sure the len is smaller then the QByteArray size!!!
      That should do the trick I think.
      Greetz

      Greetz, Jeroen

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mcosta
        wrote on 3 May 2013, 10:45 last edited by
        #3

        Hi you can use code like this
        @
        QDataStream input (...);
        QByteArray buffer;
        int length = ...;

        char temp [length];
        input.readRawData (temp, length);
        buffer.append (temp, length);
        @

        or

        @
        QDataStream input (...);
        QByteArray buffer;
        int length = ...;

        char temp* = 0;
        input.readBytes (temp, length);
        buffer.append (temp, length);
        delete [] temp;
        @

        Once your problem is solved don't forget to:

        • Mark the thread as SOLVED using the Topic Tool menu
        • Vote up the answer(s) that helped you to solve the issue

        You can embed images using (http://imgur.com/) or (http://postimage.org/)

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Code_ReaQtor
          wrote on 3 May 2013, 10:49 last edited by
          #4

          [quote author="Jeroentje@home" date="1367577761"]Hi,
          The QDateSteam is most likely set to a QIODevice? You should be able to use the readyRead() function of the QIODevice when new data is ready to be read. Or in the handling slot check the amount of bytes ready to read, then when all is in, read all available data with the int readRawData ( char * s, int len ) making sure the len is smaller then the QByteArray size!!!
          That should do the trick I think.
          Greetz[/quote]

          I am sorry if I wasn't too clear with it. The problem is not with QDataStream or with signal-slot implementation. I am reading a "binay file" and data/device is already available. It has a specific structure (header, etc.) and let's say I was able to obtain the "length", next thing to do is to read the succeeding bytes (using the length specified, of course) and saving it into a QByteArray. I wanted to find a better alternative in the "for" loop in the above code.

          Please visit my open-source projects at https://github.com/Code-ReaQtor.

          1 Reply Last reply
          0
          • C Offline
            C Offline
            Code_ReaQtor
            wrote on 3 May 2013, 11:00 last edited by
            #5

            Thank you @mcosta. The second code works (but changing "char temp* = 0"; into "char *temp = 0;").

            However, it became slower. I am using QElapsedTimer to check for speed.

            Reading the same file, my code results to 67847 nsecs
            while the code you suggested results to 859396 nsecs
            which is a big number for me.

            Please visit my open-source projects at https://github.com/Code-ReaQtor.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Code_ReaQtor
              wrote on 3 May 2013, 11:20 last edited by
              #6

              Thank you again mcosta, the first code results into a better speed.

              @QElapsedTimer timer; //for measuring speed in nsecs
              timer.start();
              char *temp = new char[length]; //need to change into this, compiler throws error: "expected constant expression"
              input.readRawData(temp, length);
              buffer.append(temp, length);
              delete [] temp;
              qDebug() << timer.nsecsElapsed();@

              Your code = 22134 nsecs
              My code = 57742 nsecs

              NOTE: QElapsedTimer is NOT accurate but I think it is PRECISE.

              Thanks. It is now solved!

              Please visit my open-source projects at https://github.com/Code-ReaQtor.

              1 Reply Last reply
              0
              • J Offline
                J Offline
                Jeroentjehome
                wrote on 3 May 2013, 11:31 last edited by
                #7

                Hi, what might speed up the process is to not copy the data into a temp buffer.
                Maybe something like this:
                @
                QByteArray newBuf(file.readAll ());
                @
                Then the newBuf will be a deep copy of the data from the file. You could also use the read(length) function of the QIODevice.
                The question that comes to mind now is why you really need the QDataStream Input if you copy the entire contense of the file anyway?
                Maybe I'm missing the big picuture here, but hope I could be of assistance anyway.
                Greetz

                Greetz, Jeroen

                1 Reply Last reply
                0
                • J Offline
                  J Offline
                  Jeroentjehome
                  wrote on 3 May 2013, 11:32 last edited by
                  #8

                  @Code_Reaqtor
                  What does my option give you as a result? Just curious to know.
                  Greetz

                  Greetz, Jeroen

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Code_ReaQtor
                    wrote on 3 May 2013, 12:05 last edited by
                    #9

                    [quote author="Jeroentje@home" date="1367580778"]What does my option give you as a result? Just curious to know.
                    Greetz[/quote]

                    The reason why is that I am reading a "binary file" and it has a structure composed of "blocks", etc. each block has a specific size/length. It can't be done by reading the whole file. QDataStream works better. Take the example below, it "simply" shows the structure of the file:

                    @Size of Block 1
                    Content of Block1
                    Size of Block2
                    Content of Block2
                    Size of Block3
                    Content of Block3
                    ...etc@

                    PS: This is not the "real" file structure. It is just an example.

                    Please visit my open-source projects at https://github.com/Code-ReaQtor.

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      Jeroentjehome
                      wrote on 3 May 2013, 12:50 last edited by
                      #10

                      Ah, Oke,
                      Got it.
                      If you only open the file ones and read out all the blocks in sequence you still could do it with an QIODevice option. The file will be kept at the position it was last read, so a sequence of read(xbytes) will shift the file reader only as far as the read takes it. Still no need to copy the data ;-)
                      Don't want to say you option is bad or wrong!! Just because you needed the ultimate fast speed it might be faster then coping data multiple times:
                      1 - QDataStream to temp buffer
                      2 -temp buffer to QByteArray
                      The Qfile inherits QIODevice, so is able to do read and peek, so the:
                      @
                      QByteArray newBuffer (file.read(yourdesiredsize));
                      @
                      This voids the double extra copy if I'm not mistaken, but as said before, it might not be suitable in your case if the file is opened/closed etc.

                      Greetz, Jeroen

                      1 Reply Last reply
                      0
                      • C Offline
                        C Offline
                        Code_ReaQtor
                        wrote on 3 May 2013, 13:58 last edited by
                        #11

                        @Jeroentje, yes I think that speeds up access. I might take that as an option. But for now I'll stick with the current method.

                        BTW, "this":https://github.com/Code-ReaQtor/libqpsd is the code I am talking about. The structure is a little complicated so I can't think of better ways in integrating your method.

                        Thank you all for suggestions!

                        Please visit my open-source projects at https://github.com/Code-ReaQtor.

                        1 Reply Last reply
                        0

                        1/11

                        3 May 2013, 10:35

                        • Login

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