Accessing files using Qt

Files are a specialization of a generalized notion—that of a byte stream that resides somewhere else. Qt encapsulates the more generalized notion of byte streams in its QIODevice class, which is the parent class for QFile as well as network I/O classes such as QTcpSocket. We don't directly create a QIODevice instance, of course, but instead create a subclass such as QFile and then work with the QFile instance directly to read from and write to the file.

Tip

Files and network access usually take time, and thus, your applications shouldn't work with them on the main thread. Consider creating a subclass of QThread to perform I/O operations such as reading from files or accessing the network.

To begin working with a file, we first must open it using the open method. The open method takes a single argument, the manner in which the file should be opened, a bitwise combination of the following:

  • QIODevice::ReadOnly: This is used for read-only access
  • QIODevice::WriteOnly: This is used for write-only access
  • QIODevice::ReadWrite: This is used for read-and-write access
  • QIODevice::Append: This is used to only append to the file
  • QIODevice::Truncate: This is used to truncate the file, discarding all previous contents before writing
  • QIODevice::Text: This is used to treat the file as text, converting new-line characters to the platform representation during reading and writing
  • QIODevice::Unbuffered: This is used to bypass any buffering of the input and output

These flags can be combined using the bitwise binary-or operator, |. For example, a common combination is QIODevice::ReadWrite | QIODevice::Text to read and write a text file. In fact, QIODevice:ReadWrite is defined as QIODevice::Read | QIODevice::Write internally.

Once you open the file, you can read a number of bytes by calling the file's read method and passing the number of bytes to read; the resulting QByteArray object contains the data to read. Similarly, you can write QByteArray by calling write, or use the overloaded write method that takes a constant char *. In either case, write also takes the number of bytes to write. If all you want to do is read the entire contents of a file into a single buffer, you can call readAll, which returns QByteArray of the entire contents of the file.

Some QIODevice subclasses such as QFile are seekable; that is, you can position the read/write cursor at any point in the file, or determine its position. You can use the seek method to position the cursor at a particular position in the file, and pos to obtain the current location of the file cursor. Note that other QIODevice subclasses like those for network I/O don't support seek and pos, but fail gracefully if you attempt to use these methods.

If you want to peek at the data without actually moving the cursor, you can call peek and pass the number of bytes to return; the result is a QByteArray. Calling read after peek returns the same data, because peek doesn't advance the cursor past the data you've peeked at. The peek method is handy when creating a complex parser that needs to know about incoming data in more than one place of its implementation; you can peek at the data, make a decision about how to parse the data, and then call read later to get the data.

To determine whether or not you're at the end of a file and there's no more data to read, you can call atEnd, which returns true if there is no more data to read. If you want to know how many bytes there are in the file, we can call bytesAvailable, which returns the number of bytes available for reading (if known; a network socket might not carry that information, of course).

When working with files, we often need to work with directories as well. The QDir class lets us examine the contents of a directory, determine whether a file or directory exists or not, and remove a file or directory. One thing to note is that regardless of the directory separator path used by the host platform, Qt always uses a forward slash / to denote directories, so even if we're writing a Qt program for Windows, we use forward slashes, not back slashes. This makes it easy to write cross-platform compatible code that runs on both Windows and Linux without the need to use special case for the directory handling code.

First, create an instance of QDir by passing a file path; after that, you can do the following with it:

  • Get an absolute path to the directory by calling absolutePath
  • Switch to a different valid directory by calling cd
  • Get a list of files in the directory by calling entryInfoList
  • Determine whether a specific file or directory exists by calling exists
  • Determine whether the directory is the root of the filesystem by calling isRoot
  • Remove a file by calling remove and passing the name of the file to remove
  • Rename a file by calling rename
  • Remove an empty directory by calling rmdir and passing the name of the directory to remove
  • Compare two directories using the == and != operators

Of course, locations of files, such as application preferences and/or temporary files, differ from platform to platform; the QStandardPaths class has a static method standardLocations that returns a path to the kind of storage we're looking for. To use it, we pass a value from the QStandardPaths::StandardLocation enumeration, which has values such as:

  • DesktopLocation: This returns the desktop directory
  • DocumentsLocation: This returns the documents directory
  • MusicLocation: This returns the location of music on the filesystem
  • PicturesLocation: This returns the location of photos on the filesystem
  • TempLocation: This returns the path to store temporary files
  • HomeLocation: This returns the path to the current user's home directory
  • DataLocation: This returns a path to an application-specific directory for persistent data
  • CacheLocation: This returns a path to where the application can cache data
  • ConfigLocation: This returns a path to where the application can store configuration settings

    Note

    For more information about files and network IO, see the Qt documentation at http://qt-project.org/doc/qt-5/io-functions.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset