Reading file byte by byte
-
Hi,
Is it possible to read a file (extension unknown because it may vary), and simply read it byte by byte or whatever?
I would like to be able to open a file (like you can with HexEditors) and save those values somewhere (in a string variable or so). I understand that those values won't mean anything to me when I look at them but I would be able to copy that file (write contents from string variable to a new file), and then save that new file.Is this possible, and how?
Thank you.
-
you could just copy the file using QFile::copy.
you can also read a file to a QByteArray with readAll function, and save it to another file with write function -
Thanks for the quick reply!
This option occurred to me and I've dropped the idea. Here is why>
I don't know what kind of files my program will be using. It might be .txt or .xlsx or whatever.Now, if its txt your suggestion works perfectly, but if its something Qt doesn't know how to read (Excel for example), then it fails.
However, HxD (hex editor I have installed) reads the xlsx file and prints out hexadecimal values of it. I of course can't use it that way, but I still have some kind of read of that file (to store in a database for example, or copy it, or something). So I was hoping Qt can do a thing similar to that. -
You can read byte by byte if you want. Use the member function 'read(char*, qint64)'.
QFile file; char file_data; file.open(QIODevice::ReadOnly); while(!file.atEnd()) { // return value from 'file.read' should always be sizeof(char). file.read(&file_data,sizeof(char)); // do something with 'file_data'. } file.close();
When you open the file don't include the option QIODevice::Text. With this flag set Qt will be looking for line terminators and trying to convert them. With binary files this scrambles the data.
If you know the data will be formatted a specific way (an array of double precision numbers for example) you can use this to your advantage and read in blocks of 8 bytes (sizeof(double)).
You can tell if the file is binary or text by taking a sample of the data and look for anything below ascii 0x20 that is not a formatting character (\r,\n,\t). Some text files (rare but not unheard of) are unicode so you should exclude 0x00 if deciding if the file is binary.
-
QFile file("C:\\Users\\s\\Desktop\\bom1.xlsx"); char file_data; QString string; if(!file.open(QFile::ReadOnly)) { qDebug() << " Could not open the file for reading"; return; } while(!file.atEnd()) { // return value from 'file.read' should always be sizeof(char). file.read(&file_data,sizeof(char)); string.append(file_data); // do something with 'file_data'. } file.close(); QFile out("C:\\Users\\s\\Desktop\\bom2"); if(!out.open(QFile::WriteOnly)) { qDebug() << " Could not open the file for writing"; return; } const char* upis = string.toStdString().c_str(); out.write(upis); out.close();
So I tried this and it doesn't work. It copied some values, but it stopped when if first occurred empty space.
Look> Above is the line from copied file, and below it's original file
-
Hi,
No it didn't stop but you are storing your char in a QString which will treat
\0
as a terminating char (which is normal) What you want to use in your case is a QByteArray. -
I missed a part of your code:
"""
const char* upis = string.toStdString().c_str(); << Why ?
out.write(upis);
"""You're taking the c-string representation of a temporary std::string, which you are lucky is still accessible. Then you call write with a const char * without giving it's size, so the first \0 will act as a string termination character.
QFile::write has an overload for QByteArray so just call
out.write(string)
(also, you shouldn't call a QByteArray string, it's even more confusing)