Qt learning path (56): binary file read/write

Source: Internet
Author: User

Today, we start to enter another part of Qt: file read/write, that is, IO. File read/write is required in many applications. Qt provides IO abstraction through QIODevice, which has the ability to read and write bytes. Common IO read/write classes include the following:

QFlie Access the local file system or embed Resources
QTemporaryFile Create and access temporary files in the local file system
QBuffer Read/write QByteArray
QProcess Run external programs to process inter-process communication
QTcpSocket TCP Network Data Transmission
QUdpSocket Transmit UDP Packets
QSslSocket Use SSL/TLS to transmit data
QProcess, QTcpSocket, QUdpSoctet, and QSslSocket are sequential access devices. Their data can only be accessed once, that is, you can only access the device from the first byte until the last byte. QFile, QTemporaryFile, and QBuffer are random access devices. You can access the device any number of times from any location, and use the QIODevice: seek () function to locate the file pointer. In terms of access methods, Qt provides two high-level abstractions: Using QDataStream for binary access and using QTextStream for text access. These classes can help us control byte sequence and text encoding, freeing programmers from this problem. QFile is very convenient for accessing independent files, whether in the file system or in the Application resource file. Qt also provides two classes, QDir and QFileInfo, for processing folder-related transactions and viewing file information. This time we will start with reading and writing binary files. The simplest way to access data in binary format is to instantiate a QFile object, open the file, and then use QDataStream for access. QDataStream provides a platform-independent method for accessing data formats, including standard C ++ types, such as int and double; multiple Qt types, such as QByteArray, QFont, QImage, QPixmap, QString and QVariant, and Qt container classes, such as QList <T> and QMap <K, T>. First look at the following code:
 
 
  1. QImage image("philip.png");  
  2.  
  3. QMap<QString, QColor> map;  
  4. map.insert("red", Qt::red);  
  5. map.insert("green", Qt::green);  
  6. map.insert("blue", Qt::blue);  
  7.  
  8. QFile file("facts.dat");  
  9. if (!file.open(QIODevice::WriteOnly)) {  
  10.     std::cerr << "Cannot open file for writing: " 
  11.               << qPrintable(file.errorString()) << std::endl;  
  12.     return;  
  13. }  
  14.  
  15. QDataStream out(&file);  
  16. out.setVersion(QDataStream::Qt_4_3);  
  17.  
  18. out << quint32(0x12345678) << image << map; 
Here, we first create a QImage object, a QMap <QString, QColor>, then use QFile to create a file named "facts. dat", and then open it in write-only mode. If it fails to be opened, return directly; otherwise, we will use the QFile pointer to create a QDataStream object and set the version. This will be explained in detail later, just like the cout of std, use the <operator to output the result. 0x12345678 becomes a "magic number", which is often used in binary file output. The binary format we define usually has such a "magic number" for marking the file format. For example, when writing 0x12345678 to a file, we first check whether the number is 0x12345678. If not, this is not a recognizable format, therefore, you do not need to read data. Generally, the binary format has such a magic number. For example, the magic number of the Java class file is 0 xCAFE BABE (a very Java name), which can be viewed using a binary viewer. The magic number is a 32-bit unsigned integer, so we use the quint32 macro to obtain a platform-independent 32-bit unsigned integer. In this Code, we use a qPrintable () Macro, which converts the QString object to const char *. Note that we are using the C ++ standard error output cerr, so this conversion is required. Of course, the QString: toStdString () function can also perform the same operation. The read process is very simple. It should be noted that the read process must correspond to the write process one by one, that is, the first magic number written to the quint32 type, the first read must also be in quint32 format, such
 
 
  1. quint32 n;  
  2. QImage image;  
  3. QMap<QString, QColor> map;  
  4.  
  5. QFile file("facts.dat");  
  6. if (!file.open(QIODevice::ReadOnly)) {  
  7.     std::cerr << "Cannot open file for reading: " 
  8.               << qPrintable(file.errorString()) << std::endl;  
  9.     return;  
  10. }  
  11.  
  12. QDataStream in(&file);  
  13. in.setVersion(QDataStream::Qt_4_3);  
  14.  
  15. in >> n >> image >> map; 
Okay, I read the data. Please use it everywhere! What is the use of this version? For binary read/write, with the upgrade of Qt, the same content may have different read/write methods, for example, it may be changed from large-end writing to small-end writing, in this case, the content written in the old version of Qt cannot be correctly read, so you need to set a version number. For example, here we use QDataStream: Qt_4_3, Which means we use Qt 4.3 to write data. In fact, the current maximum version number is QDataStream: Qt_4_6. In this case, Qt versions earlier than MySQL 4.3 cannot read and write the file content correctly. So the question is: Isn't it possible to use the latest Qt to read and write this version in a hard-coded manner? One solution is to write not only a magic number, but also the version of the file. For example:
 
 
  1. QFile file("file.xxx");  
  2. file.open(QIODevice::WriteOnly);  
  3. QDataStream out(&file);  
  4.  
  5. // Write a header with a "magic number" and a version  
  6. out << (quint32)0xA0B0C0D0;  
  7. out << (qint32)123;  
  8.  
  9. out.setVersion(QDataStream::Qt_4_0);  
  10.  
  11. // Write the data  
  12. out << lots_of_interesting_data; 
The version number of this file. xxx file is 123. In our opinion, if the version number is 123, it can be read using Qt_4_0. Therefore, to read the code, you need to determine the following:
 
 
  1. QFile file("file.xxx");  
  2.  file.open(QIODevice::ReadOnly);  
  3.  QDataStream in(&file);  
  4.  
  5.  // Read and check the header  
  6.  quint32 magic;  
  7.  in >> magic;  
  8.  if (magic != 0xA0B0C0D0)  
  9.      return XXX_BAD_FILE_FORMAT;  
  10.  
  11.  // Read the version  
  12.  qint32 version;  
  13.  in >> version;  
  14.  if (version < 100)  
  15.      return XXX_BAD_FILE_TOO_OLD;  
  16.  if (version > 123)  
  17.      return XXX_BAD_FILE_TOO_NEW;  
  18.  
  19.  if (version <= 110)  
  20.      in.setVersion(QDataStream::Qt_3_2);  
  21.  else 
  22.      in.setVersion(QDataStream::Qt_4_0);  
  23.  
  24.  // Read the data  
  25.  in >> lots_of_interesting_data;  
  26.  if (version >= 120)  
  27.      in >> data_new_in_XXX_version_1_2;  
  28.  in >> other_interesting_data; 
In this way, we can process binary data read and write perfectly.

This article is from the "bean space" blog, please be sure to keep this source http://devbean.blog.51cto.com/448512/293892

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.