T B H P N

Code Artistry - C++ File System Library

Initial Thoughts:

C++11 has a lot of useful features, many new to the latest 2011 standard, e.g., range-based for loop, uniform initialization, type inference with auto, new smart pointers, lambda functions, move constructors and assignments, etc. One of the things that was discussed but not adopted was the addition of file and directory management facilities in the standard C++ library.

Projects for CSE687 - Object Oriented Design and CSE775 - Distributed Objects often require us to find, using C++ code, files on specific directory paths that match a specified pattern. So not having file and directory management libraries means we get to write a lot of low-level code using platform specific APIs or interoperate with code developed in languages that do provide that library support, like C#. While that is not that difficult to do, it would be very convenient to have native C++ libraries that provide such support.

Background:

CSE775 - Distributed Objects is concerned with system programming for both Windows and Linux platforms. The first assigned project requires development of components using the Microsoft Component Object Model (COM) on Windows and components on Linux that use the same model, e.g., code accessed through interfaces and object factories and that uses reference counting management of object life-time.

For the second major project each student selects from a list of suggestions. Most of these projects explore some interesting platfrom that will require student research to learn a new, for them, technology. They then propose development of an application, they will develop, that illustrates how the technology works and will be technically interesting for the rest of the class. Many of these projects are expected to create applications that run on both Windows and Linux or that have components that interoperate across these platforms.

Core Idea:

In order to support cross-platform development we have been working on libraries that provide access to system artifacts: files, directories, threads and locks1, process management, and socket-based communication. The idea is for the libraries to host the same interfaces on both platforms while using the underlying platform APIs2. That way we can build applications out of code common to both platforms that use these Windows or Linux libraries without change.

Building common Graphical User Interfaces (GUI)s provide an interesting challenge which we will discuss in a future Blog page.

Figure 1 - File System Classes

Design:

Here, we focus on our FileSystem library that supports operations on the file systems of either Windows or Linux through the same set of interfaces.

The FileSystem library contains four main classes: Directory, Path, FileInfo, and File, with another public helper class Block and private helper class FileSystemSearch. The main classes are modeled after similar classes in the .Net System.IO namespace.

Directory is composed of static member functions for manipulating directories and files. For example, Directory::getFiles(...) returns a std::vector<string> containing the names of files on a specified path that match a specified pattern.

Path supports parsing fully qualified file specifications into path, file name, and extension and composing those parts into a file specification. Its function getFullFileSpec(...) supports converting a relative path into an absolute path.

The FileInfo class provides facilities for retrieving directory properties about a directory entry, like date of last modification, size, and whether it is a file or directory. The class also supports comparing properties of two specified files.

The File class supports opening, reading lines or blocks of bytes, writing lines or blocks of bytes, and testing FileStream state.

Finally, the Block class wraps an array of bytes for read and write operations on instances of the File class. Blocks are most useful for file transfers with chunking - breaking a file into pieces for transmission over a socket-based channel.

Figure 2 - File System Output

Typical Output:

Demo output is presented in Figure 2, which shows construction test output for some of the main classes.

Source Code:

This FileSystem library is written in C++ using Visual Studio 2013 and compiles and runs using Visual Studio 2013 as well. You will find the code here:

FileSystem- Windows library

This code bears a copyright © that grants all rights to users except the right to publish and requires retention of the copyright notice.

Conclusions:

The C++ FileSystem library has proven to be almost as easy to use as its .Net counterpart System.IO. The library has been used by several classes to support their project work and found to be sufficient for most project needs.

  1. C++ now supports, under the C++11 standard, threads, locks, and atomics as part of the standard C++ library. Thus we no longer need to maintain the thread and locks classes we've used before the new standard was implemented for the compilers we use, e.g., Visual Studio and GCC.
  2. That is, of course, exactly what the C++ standard library does. We are simply augmenting the standard library using the same approach.

Newhouse