简体   繁体   中英

How to get number of bytes read from QTextStream

The following code I am using to find the number of read bytes from QFile. With some files it gives the correct file size, but with some files it gives me a value that is approximatively fileCSV.size()/2. I am sending two files that have same number of characters in it, but have different file sizes link text . Should i use some other objects for reading the QFile?

QFile fileCSV("someFile.txt");
if ( !fileCSV.open(QIODevice::ReadOnly | QIODevice::Text))
   emit errorOccurredReadingCSV(this);
QTextStream textStreamCSV( &fileCSV );        // use a text stream
int fileCSVSize = fileCSV.size());
qint64 reconstructedCSVFileSize = 0;
while ( !textStreamCSV.atEnd() )
{
     QString line = textStreamCSV.readLine();         // line of text excluding '\n'
     if (!line.isEmpty())
     {
         reconstructedCSVFileSize += line.size(); //this doesn't work always
         reconstructedCSVFileSize += 2;
      }
    else
       reconstructedCSVFileSize += 2;
}

I know that reading the size of QString is wrong, give me some other solutions if you can.

Thank you.

I guess it is because QString::size() returns the number of characters. If your text file is in UTF16 and , say, x bytes long, this will correspond with x/2 characters.

Edit: If you want to know the exact size of a read line, you can just use QFile::readLine() . This returns a QByteArray of which the number of bytes can be queried using size() .

There is a similar question: QTextStream behavior searching for a string not as expected . You may check my answer for that.

Briefly: to do correct calculation you should mark begin of line with pos() and end of line after reading with pos(). Like this:

qint64 newFileSize = 0;
while ( !f.atEnd() )
{
  const qint64 begin = f.pos();
  const QString line = f.readLine();
  const qint64 end = f.pos();
  // TODO: some your actions
  // ...
  const qint64 realLengthOfLine = end - begin;
  newFileSize += realLengthOfLine;
}

I made a solution with QByteArray. The solution is:

QFile fileCSV("someFile.txt"); 
if ( !fileCSV.open(QIODevice::ReadOnly | QIODevice::Text)) 
   emit errorOccurredReadingCSV(this); 
while ( !fileCSV.atEnd())
{      
    QByteArray arrayCSV = fileCSV.readLine();
    reconstructedCSVFileSize += arrayCSV.size();
    QTextStream textStreamCSV(arrayCSV);
    QString line = textStreamCSV.readLine();
}

But there is a problem. Look close the files that I am sending files2.zip .

When i am reading biggerFile.csv with this approach, the first line is properly read, the size of the string is 108, also the number of characters is 108. The number returned by arrayCSV.size() is 221. When i am reading the second line, the size of the string is 50, but the number of characters is 25. The number returned by arrayCSV.size() is 51. When i open the string with debuger, the string is empty, although its size is 50. I guess this behavior is because the first line is written with one encoding, while the other is written with different encoding, causing QTextStream to behave non properly.

When i am reading smallerFile.csv, everything is ok. The size of the string is 16, also the number of characters is 16(without the \\n character). The number returned by arrayCSV.size() is 18. The second line is also properly read. The size of the string is 25, also the number of characters is 25. The number returned by arrayCSV.size() is 25.

The first code that i have posted, reads the strings properly from both files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM