FBB::Filesystem - class offering std::filesystem facilities
#include <bobcat/filesystem>
Linking option: -lbobcat
This header file also includes the std::chrono header
file.
The Bobcat class FileSystem is a plain wrapper around the
facilities offered by the C++ std::filesystem namespace.
FileSystem was developed because the use of the
std::filesystem facilities is considered overly complex: too many
free functions having signatures resembling C, and therefore not
object-based. Its std::filesystem::path type offers several nice
features which are then usable via the path member functions, but
functions manipulating the file system aren’t members, but are
defined as free functions requiring path arguments.
The class FileSystem offers almost all
std::filesystem facilities via its member functions. Except for some
(static) members all facilities operate on data stored inside
FileSystem objects.
The class FileSystem is an extensive class: over-all it
contains about 60 constructors, operators and members. It’ll probably
take a while before a mental picture of what the class offers has been
attained, but at least it embeds all components of the
std::filesystem namespace.
Note:
- o
- The class FileSystem uses std::chrono::file_clock, which is
available since the C++-2a standard: specify the --std=c++2a
(or more recent) compiler option when using FileSystem.
FBB
All constructors, members, operators and manipulators, mentioned in this
man-page, are defined in the namespace FBB.
FBB::FS - internally used only, covered in this
man-page
Typedefs:
- o
- DirEntry - std::filesystem::directory_entry
- o
- DirIter - std::filesystem::directory_iterator
- o
- EC - std::error_code
- o
- FileClock - std::chrono::file_clock
- o
- FileType - std::filesystem::file_type
- o
- Path - std::filesystem::path
- o
- Perms - std::filesystem::perms
- o
- RecursiveIter -
std::filesystem::recursive_directory_iterator
- o
- FileStatus - std::filesystem::file_status
- o
- SystemClock - std::chrono::system_clock
FSOptions:
- o
- enum FSOptions:
contains the following values, inherited by FileSystem. Options up to
CP_MASK are primarily used by the copy member, options
beyond CP_MASK are used by setPermissions:
NEW copy is only performed if the destination
doesn’t yet exist
REPLACE copy is only performed if the destination
exists but it is replaced
UPDATE copy is only performed if the destination
is older than the filesystem entry to copy
RECURSIVE directories are recursively copied; can be
combined with CP_SYMLINKS, SKIP_SYMLINKS,
ONLY_DIRS
CP_SYMLINKS symlinks are copied as symlinks
SKIP_SYMLINKS symlinks are ignored
ONLY_DIRS only the directory structure is copied
other entries in directories are ignored
SYMLINK with copy: define a symlink to the current
entry
HARDLINK with copy: define a hard link to the current
entry
FILE with copy: only files are processed, not
directories
CP_SYMLINK copies a symlink to a symlink
NEW_SYMLINK defines a non-existing (directory) symlink
NEW_LINK create_hard-link
CP_MASK all the above enum values
RESET replace the current permissions
ADD add to the current permissions
REMOVE remove the specified permissions
All bit-wise operators are available for FSOptions
values.
The class FileSystem defines one static data member:
std::error_code s_errorCode. All FileSystem objects can use
this error_code object after calling their function call operator.
E.g.,
FileSystem fs;
fs();
Once fs() has been called members called by fs
accepting error_code arguments receive s_error_code as their
argument. It’s also possible to use other error_code objects,
or not to use error_code arguments (which is the default). See also
the description of the function call operator below.
Path arguments can also be arguments of types from which
Path objects can be constructed (e.g., std::string, char const
*, raw string literal).
FileSystem objects contain two data members: a Path
and an EC *. When FileSystem objects are initialized their
EC * is set to 0.
- o
- Filesystem():
The default constructor constructs an empty object, not using the
class’s static s_errorCode object;
- o
- Filesystem(Path const &path, bool useEC = true):
The object is initialized with a copy of path. By default
useEC == true, in which case it uses the class’s
static s_errorCode object;
- o
- Filesystem(Path &&path, EC &ec):
The object is initialized with a copy of path, passing ec to
members supporting EC arguments;
- o
- Filesystem(Path const &tmp, bool useEC = true):
The object moves tmp to its internal path. By default
useEC == true, in which case it uses the class’s
static s_errorCode object;
- o
- Filesystem(Path &&tmp, EC &ec):
The object moves tmp to its internal path, passing ec
to members supporting EC arguments.
Copy and move constructors (and assignment operators) are
available. The newly constructed or assigned object use the same EC
specification as their source (right-hand side) objects.
Type arguments can be arguments of type FileSystem,
Path or types from which Path objects can be constructed (e.g.,
std::string, char const *, raw string literal).
- o
- std::istream &operator>>(std::istream &in, FileSystem
&rhs):
extracts a path specification from in, and initializes
rhs with the extracted path;
- o
- std::ostream &operator<<(std::ostream &out, FileSystem
const &rhs):
inserts the object’s path into out;
- o
- bool operator==(FileSystem const &lhs, FileSystem const
&rhs):
returns true if lhs and rhs refer to the same file
system entry. An exception is thrown if at least one argument
doesn’t refer to an existing file system entry and the lhs
operand hasn’t specified an EC (see operator()()
below). This operator calls the member sameAs for its lhs
argument;
- o
- FileSystem &operator/=(Type const &arg):
arg is appended to the object’s path data member. If
the path data member did not already end in
’/’ then /arg is appended;
- o
- FileSystem &operator+=(Type const &arg):
arg is appended to the object’s path data member;
- o
- FileSystem [const] &operator()(EC &ec = s_errorCode)
[const]:
this operator activates passing EC arguments to member function
accepting such arguments. By calling this operator without argument member
functions receive FileSystem’s s_errorCode. Alternatively
another (e.g., local) error_code object can be specified which will
then be passed to members accepting error_code arguments. Example:
std::error_code ec;
FileSystem fs;
fs(ec);
Using EC arguments is configured separately for each
FileSystem object. The member noEC can be used to suppress
passing EC arguments to std::filesystem functions;
Type arguments can be arguments of type FileSystem,
Path or types from which Path objects can be constructed (e.g.,
std::string, char const *, raw string literal).
All members can use EC objects to prevent exceptions being
thrown when the members cannot perform their tasks.
- o
- FileSystem absolute() const:
returns a FileSystem object containing the absolute path of the
calling object’s Path, which does not have to exist.
Relative directory specifications are kept: absolute simply
prefixes the current working directory to the calling object’s
Path;
- o
- FileSystem canonical() const:
returns a FileSystem object containing the canonical absolute path of
the calling object’s Path, from which all relative
specifications have been removed. Path must refer to an existing
file system entry;
- o
- bool copy(Type const &dest, FSOptions cpOptions = DEFAULT):
copies the object’s file system entry to dest. It is covered
in detail in the section COPYING FILE SYSTEM ENTRIES below;
- o
- uintmax_t count() const:
returns the number of hard-link counts of the calling FileSystem
object. The file system entry must exist;
- o
- char const *c_str() const:
returns the calling object’s PATH specification as a
NTBS;
- o
- static FileSystem cwd([EC &ec]):
this static member returns the current working directory (cwd). If the cwd
cannot be determined then an exception is thrown, unless an EC
argument is specified, in which case the EC argument provides
information about the failure;
- o
- FileSystem destination() const:
returns a FileSystem object containing the (symlink) destination of
the calling object, which must refer to a symlink;
- o
- DirEntry directory() const:
returns a DirEntry for the calling object. The calling object does
not have to refer to a directory, and not even to an existing file system
entry;
- o
- Ranger<DirIter> dirRange() const:
returns a pair of directory iterators non-recursively visiting all entries
referred to by the calling object, which must specify a directory name
(see also the member recursiveRange). Example:
for (auto const &entry: fs.dirRange())
cout << entry << ’\n’;
- o
- static std::error_code &errorCode():
this static member returns a reference to FileSystem’s static
(modifiable) EC data member.
- o
- bool exists() const:
returns true if the current object’s file system entry
exists;
- o
- static bool exists(FileStatus status):
returns true if status indicates that the current file system
entry exists (see also the member status below);
- o
- std::string extension() const:
returns the extension (including the initial dot (.) of the calling
object);
- o
- FileClock::time_point fcModification() const:
returns the FileClock::time_point of the (existing) file system entry
represented by the calling object;
- o
- std::string filename() const:
returns the filename (i.e., the path name from which all but the last
element has been removed). If the calling object doesn’t contain a
filename (as with ./ or /) then and empty string is
returned;
- o
- bool hasExtension() const:
returns true if the calling object’s Path has an
extension;
- o
- bool hasFilename() const:
returns true if the calling object’s Path contains
characters after its final / character;
- o
- bool isAbsolute() const:
returns true if the calling object’s Path starts with
/;
- o
- bool isRelative() const:
returns true if the calling object’s Path does not
start with /;
- o
- bool knownStatus() const:
this member only returns false for
std::filesystem::file_status{}. The member status is
probably more useful: non-existing entries show status values
FileType::not_found or FileType::unknown.
To check for specific statuses the functions
bool is_WHATEVER(file_status status) or
bool is_WHATEVER(path const &entry [, EC &ec])
can also be used;
- o
- bool mkDir() const:
returns true if the (plain) directory name stored in the calling
oblect could be created. This member does not create nested
sub-directories, but the directory name specified as the last
(/-separated) component of the calling object’s Path
is created if its parent directories already exist;
- o
- bool mkDir(Type const &reference) const:
same as the previous member, but the created directory receives the same
attributes (permissions) as reference;
- o
- bool mkDirs() const:
returns true if the last component of the calling object’s
Path could be created and its parent components could either be
created or already existed as directories. Only the directories are
constructed, not their entries. Use the copy member (see section
COPYING FILE SYSTEM ENTRIES below) to copy directories and
their file system entries;
- o
- SystemClock::time_point modification() const:
returns the SystemClock::time_point of the (existing) file system
entry represented by the calling object;
- o
- FileSystem [const] &noEC() [const]:
if the calling object uses an EC, then the EC won’t be
used anymore after calling this member;
- o
- FileSystem parent() const:
returns a FileSystem object initialized with the parent Path
of the calling object. The parent is equal to the calling
object’s Path from which its filename has been
removed (returning an empty object if the calling object merely contains
`/’);
- o
- Path const &path() const:
returns the current object’s Path data member. When inserting
path() into an ostream Path is surrounded by double
quotes. If that’s not required call the string member;
- o
- Perms permissions() const:
returns the permissions of the calling object, which must refer to an
existing file system entry. The returned Perms value consists of
bitwise or-ed values of the std::filesystem::perms enum class, but
can be statically cast to mode_t values which are used as argument
to chmod(2);
- o
- Ranger<[Const]Iter> range() [const]:
returns a pair of iterators visiting all components of the calling
object’s Path.Example:
for (auto const &comp: fs.range())
cout << comp << ’\n’;
- o
- FileSystem relative() const:
returns a copy of the calling object from which an initial `/’
has been removed;
- o
- bool remove() const:
returns true if the current object’s file system entry has
been removed;
- o
- size_t removeAll() const:
returns the number of (recursively) removed file system entries starting at
the calling object’s Path. The calling object doesn’t
have to specify a directory;
- o
- bool rename(Type const &newName) const:
returns true if the current file system entry could be renamed to
newName. The calling object’s Path is not
altered;
- o
- bool resize(std::uintmax_t size) const:
returns true if the current file system entry could be resized to
size;
- o
- bool sameAs(Type const &other) const:
returns true if other refers to the same file system entry as
the calling object. It is called by operator== as its lhs
member;
- o
- FileSystem &setCwd():
changes the current process’s current working directory to the
directory specified by the calling object;
- o
- static FileSystem setCwd(Path const &path [, EC &ec]):
this static member changes the current process’s current working
directory to the directory specified by its Path argument;
- o
- FileSystem &setExtension(std::string const &ext):
changes the filename extension of the current object to ext. A dot
(.) is used to separate the current object’s stem
(see below) and the extension. The resulting file name only has a single
dot;
- o
- FileSystem &setFilename(std::string const &newName):
changes the current object’s file name (including its extension) to
newName. If the current object refers to an existing file system
entry then that file system entry is kept as-is;
- o
- bool setModification(FBB::DateTime const &time):
changes the modification time of the current file system entry to the
time time-specification;
- o
- bool setModification(SystemClock::time_point const &time):
changes the modification time of the current file system entry to the
time time-specification;
- o
- FileSystem [const] &setPermissions(PermType perms, FSOptions
opt = RESET) [const]:
changes the permissions of the current file system entry to perms,
which must be statically castable to Perms. Example:
// change "entry’s" permissions to -rw-------
FileSystem{ "entry" }.setPermissions(0600);
- o
- bool setType(FileType type, bool destination = true):
it’s unclear what this function is used for. It calls
filesystem::(symlink_)status, using symlink_status when
called as type(false). It returns false if type
doesn’t match the current file system entry referred, but the type
itself isn’t modified;
- o
- uintmax_t size() const:
returns the size in bytes of the current file system entry;
- o
- FileStatus status(bool destination = true) const:
returns the filesystem::status of the current file system entry. If
the current object is a symlink and the symlink’s status is
requested then call status(false);
- o
- FileSystem stem() const:
returns the file name of the current object without its extension;
- o
- std::string string() const:
returns the current object’s Path data member as a
std::string;
- o
- static FileSystem tmpDir(Type arg [= true]):
this static member returns the file system’s directory which is by
default used for temporary files. By default tmpDir uses
FileSystem::s_errorCode objct, when calling tmpDir(false) no
EC object is used;
- o
- static FileSystem tmpDir(EC &ec):
this static member returns the file system’s directory using the
specified EC object when determining the temporay directory;
- o
- FileType type(bool destination = true) const:
returns the FileType of the current file system entry. If the current
object refers to a symlink call type(false) to receive the
symlink’s type.
The member copy(Type const &dest, FSOptions cpOptions =
DEFAULT)’s first argument specifies the name of the copied file
or directory. It’s second argument specifies the type of the
copy-operation. Options can be combined using binary operators (usually
bit_or). The following combinations are valid:
- o
- FILE - unconditionally copies the current entry to
dest;
- o
- FILE | NEW - the current entry is copied to dest if
dest does not yet exist;
- o
- FILE | REPLACE - the current entry is copied to dest if
dest already exists;
- o
- FILE | UPDATE - the current entry is only copied to dest if
it is younger than dest;
- o
- CP_SYMLINK - the current entry must be a symlink, dest may
not yet exist and becomes a symlink to the same destination as the current
entry’s destination;
- o
- NEW_LINK - dest may not yet exist. It becomes a hard-link to
the current entry. The current object must exist;
- o
- NEW_SYMLINK - dest may not yet exist. It becomes a symlink
to the current entry. If the current entry is itself a symlink then
dest becomes a symlink to the current entry, and not to the entry
the current object refers to. The current object does not have to be an
existing file system entry;
- o
- RECURSIVE - the current entry is recursively copied to dest.
If the current entry isn’t a directory then the entry itself is
copied as if RECURSIVE was not specified;
- o
- RECURSIVE | CP_SYMLINKS - like using RECURSIVE but existing
symlinks are copied as symlinks;
- o
- RECURSIVE | ONLY_DIRS - like using RECURSIVE but only the
directory structure is copied;
- o
- RECURSIVE | SKIP_SYMLINKS - like using RECURSIVE but
existing symlinks are not copied;
#include <iostream>
#include <string>
#include <exception>
#include <bobcat/filesystem>
using namespace std;
using namespace FBB;
int main(int argc, char **argv)
{
if (argc == 1)
{
cout << "1st arg: an existing file\n"
"2nd arg (optional): a directory owned by the caller\n";
return 1;
}
FileSystem fs{ argv[1] };
if (not fs.exists())
cout << "No such file " << argv[1] << ’\n’;
else
cout << "last modification date of " << argv[1] << ": " <<
fs.modification() << ’\n’;
cout << oct << "Permissions: 0" <<
static_cast<size_t>(fs.permissions()) << dec << ’\n’;
if (argc > 2)
{
cout << "Entries of " << argv[2] << ":\n";
FileSystem fs2{ argv[2] };
for (auto const &entry: fs2.dirRange())
cout << " " << entry << ’\n’;
cout << fs2.errorCode().message() << ’\n’;
}
}
bobcat/filesystem - defines the class interface
- o
- https://fbb-git.gitlab.io/bobcat/: gitlab project page;
Debian Bobcat project files:
- o
- libbobcat6: debian package containing the shared library, changelog
and copyright note;
- o
- libbobcat-dev: debian package containing the static library,
headers, manual pages, and developer info;
Bobcat is an acronym of `Brokken’s Own Base Classes And
Templates’.
This is free software, distributed under the terms of the GNU
General Public License (GPL).
Frank B. Brokken (f.b.brokken@rug.nl).