#pragma once
#include "ofConstants.h"
#include <fstream>
#if OF_USING_STD_FS
# if __cplusplus < 201703L
# include <experimental/filesystem>
namespace std {
namespace filesystem = experimental::filesystem;
}
# else
# include <filesystem>
# endif
#else
# if !_MSC_VER
# define BOOST_NO_CXX11_SCOPED_ENUMS
# define BOOST_NO_SCOPED_ENUMS
# endif
# include <boost/filesystem.hpp>
namespace std {
namespace filesystem = boost::filesystem;
}
#endif
//----------------------------------------------------------
// ofBuffer
//----------------------------------------------------------
/// \class ofBuffer
///
/// A buffer of data which can be accessed as simple bytes or text.
///
class ofBuffer{
public:
ofBuffer();
/// Create a buffer and set its contents from a raw byte pointer.
///
/// \param buffer pointer to the raw byte buffer to copy data from
/// \param size the number of bytes to read
/// \warning buffer *must* not be NULL
/// \warning size *must* be <= the number of bytes allocated in buffer
ofBuffer(const char * buffer, std::size_t size);
/// Create a buffer and set its contents from an input stream.
///
/// \param ioBlockSize the number of bytes to read from the stream in chunks
ofBuffer(std::istream & stream, std::size_t ioBlockSize = 1024);
/// Set the contents of the buffer from a raw byte pointer.
///
/// \warning buffer *must* not be NULL
/// \warning size *must* be <= the number of bytes allocated in buffer
/// \param buffer pointer to the raw byte buffer to copy data from
/// \param size the number of bytes to read
void set(const char * buffer, std::size_t size);
/// Set contents of the buffer from a string.
///
/// \param text string to copy data from
void set(const std::string & text);
/// Set contents of the buffer from an input stream.
///
/// \param stream input stream to copy data from
/// \param ioBlockSize the number of bytes to read from the stream in chunks
bool set(std::istream & stream, std::size_t ioBlockSize = 1024);
/// Set all bytes in the buffer to a given value.
///
/// \param mem byte value to set
void setall(char mem);
/// Append bytes to the end of buffer from a string.
///
/// \param buffer string to copy bytes from
void append(const std::string& buffer);
/// Append bytes to the end of the buffer from a raw byte pointer.
///
/// \warning buffer *must* not be NULL
/// \warning size *must* be <= the number of bytes allocated in buffer
/// \param buffer pointer to the raw byte buffer to copy data from
/// \param size the number of bytes to read
void append(const char * buffer, std::size_t size);
/// Request that the buffer capacity be at least enough to contain a
/// specified number of bytes.
///
/// \param size number of bytes to reserve space for
void reserve(std::size_t size);
/// Write contents of the buffer to an output stream.
bool writeTo(std::ostream & stream) const;
/// Remove all bytes from the buffer, leaving a size of 0.
void clear();
/// Request that the buffer capacity be at least enough to contain a
/// specified number of bytes.
///
/// \param size number of bytes to reserve space for
void allocate(std::size_t size);
/// Resize the buffer to contain a specified number of bytes.
///
/// If size is < the current buffer size, the contents are reduced to size
/// bytes & remaining bytes are removed. If size is > the current buffer
/// size, the buffer's size is increased to size_ bytes.
///
/// \param size number of bytes to resize the buffer to
void resize(std::size_t size);
/// Access the buffer's contents using a raw byte pointer.
///
/// \warning Do not access bytes at indices beyond size()!
/// \returns pointer to internal raw bytes
char * getData();
/// access the buffer's contents using a const raw byte pointer.
///
/// \warning Do not access bytes at indices beyond size()!
/// \returns const pointer to internal raw bytes
const char * getData() const;
OF_DEPRECATED_MSG("Use getData instead",char * getBinaryBuffer());
OF_DEPRECATED_MSG("Use getData instead",const char * getBinaryBuffer() const);
/// get the contents of the buffer as a string.
///
/// \returns buffer contents as a string
std::string getText() const;
/// Use buffer as a string via cast.
///
/// \returns buffer contents as a string
operator std::string() const;
/// set contents of the buffer from a string
ofBuffer & operator=(const std::string & text);
/// Check the buffer's size.
///
/// \returns the size of the buffer's content in bytes
std::size_t size() const;
OF_DEPRECATED_MSG("use a lines iterator instead",std::string getNextLine());
OF_DEPRECATED_MSG("use a lines iterator instead",std::string getFirstLine());
OF_DEPRECATED_MSG("use a lines iterator instead",bool isLastLine());
OF_DEPRECATED_MSG("use a lines iterator instead",void resetLineReader());
friend std::ostream & operator<<(std::ostream & ostr, const ofBuffer & buf);
friend std::istream & operator>>(std::istream & istr, ofBuffer & buf);
std::vector<char>::iterator begin();
std::vector<char>::iterator end();
std::vector<char>::const_iterator begin() const;
std::vector<char>::const_iterator end() const;
std::vector<char>::reverse_iterator rbegin();
std::vector<char>::reverse_iterator rend();
std::vector<char>::const_reverse_iterator rbegin() const;
std::vector<char>::const_reverse_iterator rend() const;
/// A line of text in the buffer.
///
struct Line: public std::iterator<std::forward_iterator_tag,Line>{
Line(std::vector<char>::iterator _begin, std::vector<char>::iterator _end);
const std::string & operator*() const;
const std::string * operator->() const;
const std::string & asString() const;
/// Increment to the next line.
Line& operator++();
/// Increment to a number of lines.
Line operator++(int);
bool operator!=(Line const& rhs) const;
bool operator==(Line const& rhs) const;
/// Is this line empty? (aka an empty string "")
bool empty() const;
private:
std::string line;
std::vector<char>::iterator _current, _begin, _end;
};
/// A line of text in the buffer.
///
struct RLine: public std::iterator<std::forward_iterator_tag,Line>{
RLine(std::vector<char>::reverse_iterator _begin, std::vector<char>::reverse_iterator _end);
const std::string & operator*() const;
const std::string * operator->() const;
const std::string & asString() const;
/// Increment to the next line.
RLine& operator++();
/// Increment to a number of lines.
RLine operator++(int);
bool operator!=(RLine const& rhs) const;
bool operator==(RLine const& rhs) const;
/// Is this line empty? (aka an empty string "")
bool empty() const;
private:
std::string line;
std::vector<char>::reverse_iterator _current, _rbegin, _rend;
};
/// A series of text lines in the buffer.
///
struct Lines{
Lines(std::vector<char>::iterator begin, std::vector<char>::iterator end);
/// Get the first line in the buffer.
Line begin();
/// Get the last line in the buffer.
Line end();
RLine rbegin();
RLine rend();
private:
std::vector<char>::iterator _begin, _end;
};
/// A series of text lines in the buffer.
///
struct RLines{
RLines(std::vector<char>::reverse_iterator rbegin, std::vector<char>::reverse_iterator rend);
/// Get the first line in the buffer.
RLine begin();
/// Get the last line in the buffer.
RLine end();
private:
std::vector<char>::reverse_iterator _rbegin, _rend;
};
/// Access the contents of the buffer as a series of text lines.
///
/// If the buffer loads a text file with lines separated by an endline
/// char '\n', you can access each line individually using Line structs.
///
/// \returns buffer text lines
Lines getLines();
/// Access the contents of the buffer as a series of text lines in reverse
/// order
///
/// If the buffer loads a text file with lines separated by an endline
/// char '\n' or '\r\n', you can access each line individually using Line structs.
///
/// \returns buffer text lines
RLines getReverseLines();
private:
std::vector<char> buffer;
Line currentLine;
};
//--------------------------------------------------
/// Read the contents of a file at path into a buffer.
///
/// Opens as a text file by default.
///
/// \param path file to open
/// \param binary set to false if you are reading a text file & want lines
/// split at endline characters automatically
ofBuffer ofBufferFromFile(const std::filesystem::path & path, bool binary=true);
//--------------------------------------------------
/// Write the contents of a buffer to a file at path.
///
/// Saves as a text file by default.
///
/// \param path file to open
/// \param buffer data source to write from
/// \param binary set to false if you are writing a text file & want lines
/// split at endline characters automatically
bool ofBufferToFile(const std::filesystem::path & path, const ofBuffer& buffer, bool binary=true);
//--------------------------------------------------
/// \class ofFilePath
///
/// Static class for working with file path strings.
///
class ofFilePath{
public:
/// Get the extension of a filename, ie. "duck.jpg" -> "jpg".
///
/// \param filename file path
/// \returns filename extension only
static std::string getFileExt(const std::filesystem::path& filename);
/// Remove extension from a filename, ie. "duck.jpg" ->"duck".
///
/// \param filename file path
/// \returns filename without extension
static std::string removeExt(const std::filesystem::path& filename);
/// Prepend path with a slash, ie. "images" -> "/images".
///
/// \param path file or directory path
/// \returns slah + path
static std::string addLeadingSlash(const std::filesystem::path& path);
/// Append path with a slash, ie. "images" -> "images/".
///
/// \param path directory path
/// \returns path + slash
static std::string addTrailingSlash(const std::filesystem::path& path);
/// Remove a path's trailing slash (if found),
/// ie. "images/" -> "images".
///
/// \param path directory path
/// \returns path minus trailing slash
static std::string removeTrailingSlash(const std::filesystem::path& path);
/// Cleaned up a directory path by adding a trailing slash if needed.
///
/// For Windows-style path strings using "\", a "\" will be added.
/// For Unix-style path strings using "/", a "/" will be added.
///
/// \param path directory path
/// \returns cleaned path + trailing slash (if needed)
static std::string getPathForDirectory(const std::filesystem::path& path);
/// Get the absolute, full path for a given path,
/// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images".
///
/// \param path file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder and want the direct path without relative
/// "../../"
/// \returns absolute path
static std::string getAbsolutePath(const std::filesystem::path& path, bool bRelativeToData = true);
/// Check if a path is an absolute (aka a full path),
/// ie. "images" -> false,
/// "/Users/mickey/of/apps/myApps/Donald/bin/data/images" -> true.
///
/// \param path file or directory path
/// \returns true if the path is an absolute path
static bool isAbsolute(const std::filesystem::path& path);
/// Get the filename of a given path by stripping the parent
/// directories ie. "images/duck.jpg" -> "duck.jpg", assumes the path is in
/// the data folder.
///
/// \param filePath file path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder and want the direct path without relative
/// "../../"
/// \returns filename
static std::string getFileName(const std::filesystem::path& filePath, bool bRelativeToData = true);
/// Get a file name without its extension,
/// ie. "images/duck.jpg" -> "duck" and
/// "images/some/folder" -> "folder"
///
/// \param filePath file path
/// \returns basename
static std::string getBaseName(const std::filesystem::path& filePath);
/// Get the enclosing parent directory of a path,
/// ie. "images/duck.jpg" -> "images", assumes the path is in the data
/// directory.
///
/// \param filePath file path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder and want the direct path without relative
/// "../../"
///\returns enclosing directory
static std::string getEnclosingDirectory(const std::filesystem::path& filePath, bool bRelativeToData = true);
/// Create the enclosing parent directory of a path, ie.
/// "images" is the enclosing directory of "duck.jpg" = "images/duck.jpg".
///
/// Assumes the path is in the data folder & automatically creates nested
/// directories as required.
///
/// \param bRecursive set to false to override automatically nested
/// directory creation
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder and want the direct path without relative
/// "../../"
/// \returns true if the enclosing directory was created
static bool createEnclosingDirectory(const std::filesystem::path& filePath, bool bRelativeToData = true, bool bRecursive = true);
/// Get the full path to the app's current working directory.
///
/// This may be the app's parent directory or the location the app was
/// launched from (aka on the commandline).
///
/// \warning This location *may* change if you or a library calls the cd()
/// std C function.
/// \returns current working directory
static std::string getCurrentWorkingDirectory();
/// Create a single path by joining path1 & path2 using a slash,
/// ie. "/hello/world" + "foo/bar" -> "/hello/world/foo/bar".
///
/// \param path1 left half of the path to join
/// \param path2 right half of the path to join
/// \returns joined path
static std::string join(const std::filesystem::path& path1, const std::filesystem::path& path2);
/// Get the full path to the application's executable file.
///
/// Mac: the binary within the application's .app bundle Contents/MacOS dir
/// Windows: the .exe
/// Linux: the binary file itself
///
/// \returns current executable path
static std::string getCurrentExePath();
/// Get the full path to the application's parent directory.
///
/// Windows & Linux: the application's parent directory
/// Mac: the Contents/MacOS folder within the application's .app bundle
///
/// \returns current executable directory
static std::string getCurrentExeDir();
/// Get the absolute path to the user's home directory.
///
/// Mac OSX: /Users/<username>
/// Windows: <root>\Users\<username>
/// Linux: /home/<username>
///
/// \returns home directory path
static std::string getUserHomeDir();
/// Make one path relative to another,
/// ie. the relative path of "images/felines/lions" to
/// "images/felines/tigers" is "../tigers".
///
/// \param from starting path
/// \param to destination path
/// \returns relative path
static std::string makeRelative(const std::filesystem::path & from, const std::filesystem::path & to);
};
/// \class ofFile
///
/// path to a file or directory
///
/// inherits from an fstream so you can read/write using the stream operators
/// once a file path has been opened
class ofFile: public std::fstream{
public:
/// file access mode
enum Mode{
Reference, //<
ReadOnly, //< read only from the file, do not write
WriteOnly, //< write only to the file, do not read
ReadWrite, //< read from and write to the file
Append //< append data to the end of the file, do not overwrite
};
/// Create an ofFile instance.
///
/// Does not refer to a specific file until you either open a file or create
/// a file or directory path.
ofFile();
/// Create a new ofFile instance and attempt to open the path as a
/// file.
///
/// Opens as a binary file with read only access by default.
///
/// \param path file path
/// \param mode file access mode depending on how you plan to use the file
/// (read only, read write, etc)
/// \param binary set to false if you are working with a text file & want
/// lines split at endline characters automatically
ofFile(const std::filesystem::path & path, Mode mode=ReadOnly, bool binary=true);
/// Create a new file path using the same path & settings of another
/// file.
///
/// \param mom ofFile instance source
ofFile(const ofFile & mom);
/// Copy the path and settings of an ofFile into this instance.
///
/// \param mom ofFile instance source
ofFile & operator= (const ofFile & mom);
~ofFile();
/// Open the path as a file.
///
/// Opens as a text file with read only access by default.
///
/// \param path file path
/// \param mode file access mode depending on how you plan to use the file
/// (read only, read write, etc)
/// \param binary set to false if you are reading a text file & want lines
/// split at endline characters automatically
/// \returns true if the path was opened
bool open(const std::filesystem::path & path, Mode mode=ReadOnly, bool binary=true);
/// Open the path as a file.
///
/// Opens as a text file with read only access by default from the current working directory without internally calling ofToDataPath.
///
/// \param path file path
/// \param mode file access mode depending on how you plan to use the file
/// (read only, read write, etc)
/// \param binary set to false if you are reading a text file & want lines
/// split at endline characters automatically
/// \returns true if the path was opened
bool openFromCWD(const std::filesystem::path & path, Mode mode=ReadOnly, bool binary=true);
/// Reopen the current file path with a different access mode.
///
/// \param mode file access mode depending on how you plan to use the file
/// (read only, read write, etc)
/// \param binary set to false if you are reading a text file & want lines
/// split at endline characters automatically
/// \returns true if the file was reopened with the new access mode(s).
bool changeMode(Mode mode, bool binary=true);
/// Close a currently open file.
void close();
/// Create a file at the current path.
///
/// Creates as a write only binary file by default.
///
/// \returns true if the file was created
bool create();
/// Create a file at a given path.
///
/// Creates as a write only binary file by default.
///
/// \param path file path
/// \returns true if the file was created
bool create(const std::filesystem::path & path);
/// Check if a file exists at the current path.
///
/// \returns true if the file exists
bool exists() const;
/// Get the current path.
///
/// \returns current path
std::string path() const;
/// Get the current path without its extension,
/// ie. "duck.jpg" ->"duck".
///
/// \returns current path file extension
std::string getExtension() const;
/// Get the filename of the current path by stripping the parent
/// directories, ie. "images/duck.jpg" -> "duck.jpg".
///
/// \returns current path filename
std::string getFileName() const;
/// \biref Get the current path without its last component,
/// ie. "images/duck.jpg" -> "images" and
/// "images/some/folder" -> "images/some".
///
/// \returns current path basename
std::string getBaseName() const;
/// Get the enclosing parent directory of a path,
/// ie. "images/duck.jpg" -> "images", assumes the path is in the data
/// directory.
///
/// \returns current path's enclosing directory
std::string getEnclosingDirectory() const;
/// \biref Get the absolute, full path of the file,
/// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images".
///
/// \returns current path as an absolute path
std::string getAbsolutePath() const;
/// Check if the current path is readable.
///
/// \returns true if readable
bool canRead() const;
/// Check if the current path is writable.
///
/// \returns true if writable
bool canWrite() const;
/// Check if the current path is executable.
///
/// \returns true if executable
bool canExecute() const;
/// Check if the current path is a file and not a directory.
///
/// \returns true if a file
bool isFile() const;
/// Check if the current path is a system link to another file or
/// directory.
///
/// \returns true if a system link
bool isLink() const;
/// Check if the current path is a directory and not a file.
///
/// \returns true if a directory
bool isDirectory() const;
/// Check if the current path is a device file.
///
/// Works on Mac & Linux which can represent devices as files, however
/// always returns false on Windows.
///
/// \returns true if a device file
bool isDevice() const;
/// Check if the current path is hidden.
///
/// Works on Mac & Linux which denote hidden files by prepending a period
/// to the filename -> ".hello", however always returns false on Windows.
///
/// \returns true if hidden
bool isHidden() const;
/// Set the writable flag of the current path.
void setWriteable(bool writeable=true);
OF_DEPRECATED_MSG("Use ofFile::setWriteable(!flag).", void setReadOnly(bool flag));
/// Set the readable flag of the current path.
void setReadable(bool readable=true);
/// Set the executable flag of the current path.
void setExecutable(bool executable=true);
/// Copy the current file or directory path to a new path.
///
/// Copies relative to the data path & does *not* overwrite by default
/// does not change the current path & assumes the new path is in the data
/// folder.
///
/// \param path destination file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder
/// \param overwrite set to true if you want to overwrite the file or
/// directory at the new path
/// \returns true if the copy was successful
bool copyTo(const std::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false) const;
/// Move the current file or directory path to a new path.
///
/// Moves relative to the data path & does *not* overwrite by default
/// does not change the current path & assumes the new path is in the data
/// folder.
///
/// \param path destination file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder
/// \param overwrite set to true if you want to overwrite the file or
/// directory at the new path
/// \returns true if the copy was successful
bool moveTo(const std::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false);
/// Rename the current file or directory path to a new path.
///
/// Renames relative to the data path & does *not* overwrite by default
/// does not change the current path & assumes the new path is in the data
/// folder.
///
/// \param path destination file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder
/// \param overwrite set to true if you want to overwrite the file or
/// directory at the new path
/// \returns true if the copy was successful
bool renameTo(const std::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false);
/// Removes the file or directory at the current path.
///
/// Does not remove non-empty directories by default.
///
/// \warning Be careful! This deletes a file or folder. :)
/// \param recursive set to true to remove a non-empty directory and its
/// contents
/// \returns true if the path was removed successfully
bool remove(bool recursive=false);
/// get the size of the file at the current file path
///
/// \returns size in bytes
uint64_t getSize() const;
// this allows to compare files by their paths, also provides sorting
// and use as key in stl containers
bool operator==(const ofFile & file) const;
bool operator!=(const ofFile & file) const;
bool operator<(const ofFile & file) const;
bool operator<=(const ofFile & file) const;
bool operator>(const ofFile & file) const;
bool operator>=(const ofFile & file) const;
//------------------
// stream operations
//------------------
// since this class inherits from fstream it can be used as a r/w stream:
// http://www.cplusplus.com/reference/iostream/fstream/
/// Read the contents of a file at the current path into a buffer.
///
/// \returns buffer with file contents
ofBuffer readToBuffer();
/// Write the contents of a buffer into a file at the current path.
///
/// \param buffer source byte buffer
/// \returns true if buffer's contents written successfully
bool writeFromBuffer(const ofBuffer & buffer);
/// Read the entire contents of the currently opened file into an
/// output stream.
///
/// This is basically an easy to use equivalent to rdbuf():
/// ie. ofLogNotice() << file.getFileBuffer();
/// write_file << file.getFileBuffer();
///
/// \return output stream
std::filebuf * getFileBuffer() const;
operator std::filesystem::path(){
return myFile;
}
operator const std::filesystem::path() const{
return myFile;
}
//-------
//static helpers
//-------
/// Copy source path to destination path.
///
/// Copies relative to the data path & does *not* overwrite by default
/// assumes the source & destination path is in the data directory.
///
/// \param pathSrc source file or directory path
/// \param pathDst destination file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data directory
/// \param overwrite set to true if you want to overwrite the file or
/// directory at the new path
/// \returns true if the copy was successful
static bool copyFromTo(const std::filesystem::path& pathSrc, const std::filesystem::path& pathDst, bool bRelativeToData = true, bool overwrite = false);
/// Move source path to destination path.
///
/// Moves relative to the data path & does *not* overwrite by default
/// assumes the source & destination path is in the data directory.
///
/// \param pathSrc source file or directory path
/// \param pathDst destination file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder
/// \param overwrite set to true if you want to overwrite the file or
/// directory at the new path
/// \warning be careful with slashes here, appending a slash when moving a
/// folder may cause mad headaches in OSX
/// \returns true if the move was successful
static bool moveFromTo(const std::filesystem::path& pathSrc, const std::filesystem::path& pathDst, bool bRelativeToData = true, bool overwrite = false);
/// Check if a file or directory exists at a given path.
///
/// \param fPath file path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder and want the direct path without relative
/// "../../"
/// \returns true if a file or directory exists
static bool doesFileExist(const std::filesystem::path& fPath, bool bRelativeToData = true);
/// Remove a file or directory at a given path.
///
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder and want the direct path without relative
/// "../../"
/// \returns true if the path was removed successfully
static bool removeFile(const std::filesystem::path& path, bool bRelativeToData = true);
private:
bool isWriteMode();
bool openStream(Mode _mode, bool binary);
void copyFrom(const ofFile & mom);
std::filesystem::path myFile;
Mode mode;
bool binary;
};
/// \class ofDirectory
///
/// Path to a directory. Can be used to query file and directory
/// contents.
///
class ofDirectory{
public:
/// Create an ofDirectory instance
///
/// Does not refer to a specific directory until you either open or create
/// a directory path.
ofDirectory();
/// Create an ofDirectory instance and attempt to open the path.
///
/// \param path directory path
ofDirectory(const std::filesystem::path & path);
/// Open a directory path, clears the current file list.
///
/// \param path directory path
void open(const std::filesystem::path & path);
/// Open a directory path relative to the current working directory without calling ofToDataPath internally, clears the current file list.
///
/// \param path directory path
void openFromCWD(const std::filesystem::path & path);
/// Close the currently open path.
void close();
/// Create a directory at the current path.
///
/// \param bRecursive set to true to automatically create nested directories
/// as required
bool create(bool recursive = false);
/// Check if a directory exists at the current path.
///
/// \returns true if exists
bool exists() const;
/// Get the current path.
///
/// \returns current path
std::string path() const;
/// Get the absolute, full path of the directory,
/// ie. "images" -> "/Users/mickey/of/apps/myApps/Donald/bin/data/images".
///
/// \return current path as an absolute path
std::string getAbsolutePath() const;
/// Check if the current path is readable.
///
/// \returns true if readable
bool canRead() const;
/// Check if the current path is writeable.
///
/// \returns true if writable
bool canWrite() const;
/// Check if the current path is executable.
///
/// \returns true if executable
bool canExecute() const;
/// Check if the current path is indeed a directory and not a file.
///
/// \returns true if a directory
bool isDirectory() const;
/// Check if the current path is hidden.
///
/// Works on Mac & Linux which denote hidden directories by prepending
/// a period -> ".hello", however always returns false on Windows.
///
/// \returns true if hidden
bool isHidden() const;
/// Set the writable flag of the current path.
///
/// \param writable set to true to make path writable
void setWriteable(bool writeable=true);
OF_DEPRECATED_MSG("Use ofDirectory::setWriteable(!flag).", void setReadOnly(bool flag));
/// Set the readable flag of the current path.
///
/// \param readable set to true to make path readable
void setReadable(bool readable=true);
/// Set the executable flag of the current path.
///
/// \param executable set to true to make path executable
void setExecutable(bool executable=true);
/// Show hidden files & directories when listing files?
///
/// Mac & Linux denote hidden directories by prepending a period
/// -> ".hello".
///
/// \param showHidden set to true to show hidden files
void setShowHidden(bool showHidden);
/// Copy the current file or directory path to a new path.
///
/// Copies relative to the data path & does *not* overwrite by default
/// does not change the current path & assumes the new path is in the data
/// directory.
///
/// \param path destination file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data directory
/// \param overwrite set to true if you want to overwrite the file or
/// directory at the new path
/// \returns true if the copy was successful
bool copyTo(const std::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false);
/// Move the current file or directory path to a new path.
///
/// Moves relative to the data path & does *not* overwrite by default
/// does not change the current path & assumes the new path is in the data
/// directory.
///
/// \param path destination file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data directory
/// \param overwrite set to true if you want to overwrite the file or
/// directory at the new path
/// \returns true if the copy was successful
bool moveTo(const std::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false);
/// Rename the current file or directory path to a new path.
///
/// Renames relative to the data path & does *not* overwrite by default
/// does not change the current path & assumes the new path is in the data
/// directory.
///
/// \param path destination file or directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data folder
/// \param overwrite set to true if you want to overwrite the file or
/// directory at the new path
/// \returns true if the copy was successful
bool renameTo(const std::filesystem::path& path, bool bRelativeToData = true, bool overwrite = false);
/// Removes the file or directory at the current path.
///
/// Does not remove non-empty directories by default.
///
/// \warning Be careful! This deletes a file or folder. :)
/// \param recursive set to true to remove a non-empty directory and its
/// contents
/// \returns true if the path was removed successfully
bool remove(bool recursive);
//-------------------
// dirList operations
//-------------------
/// Allow a file extension when listing the contents the current
/// directory path.
///
/// Setting an allowed extension enables a whitelist mode which only lists
/// extensions which have been explicitly allowed.
///
/// \param extension file type extension ie. "jpg", "png", "txt", etc
void allowExt(const std::string& extension);
/// Open and read the contents of a directory.
///
/// Uses allowed extension whitelist to ignore unwanted file types if
/// allowExt() has been called.
///
/// \param path directory path
/// \returns number of paths found
std::size_t listDir(const std::string& path);
/// Open and read the contents of the current directory.
///
/// Uses allowed extension whitelist to ignore unwanted file types if
/// allowExt() has been called.
///
/// \returns number of paths found
std::size_t listDir();
/// \returns the current path
std::string getOriginalDirectory() const;
/// Get the filename at a given position in the directory contents
/// list, ie. "duck.jpg".
///
/// \warning Call listDir() before using this function or the directory
/// contents list will be empty.
/// \throws Throws an out of bounds exception if position >= the number of
/// listed directory contents.
/// \param position array index in the directory contents list
/// \returns file or directory name
std::string getName(std::size_t position) const;
/// Get the full path of the file or directory at a given position in
/// the directory contents list.
///
/// \warning Call listDir() before using this function or the directory
/// contents list will be empty.
/// \throws Throws an out of bounds exception if position >= the number of
/// listed directory contents.
/// \param position array index in the directory contents list
/// \returns file or directory name including the current path
std::string getPath(std::size_t position) const;
/// Open an ofFile instance using the path a given position in the
/// directory contents list.
///
/// Opens as a binary file with readonly access by default.
///
/// \warning Call listDir() before using this function or the directory
/// contents list will be empty.
/// \throw Throws an out of bounds exception if position >= the number of
/// listed directory contents.
/// \param position array index in the directory contents list
/// \param mode file access mode depending on how you plan to use the file
/// (read only, read write, etc)
/// \param binary set to false if you are working with a text file & want
/// lines split at endline characters automatically
/// \returns ofFile instance
ofFile getFile(std::size_t position, ofFile::Mode mode=ofFile::Reference, bool binary=true) const;
/// Get files and directories in the directory contents list.
///
/// Directory contents are automatically listed.
///
/// \returns vector of files in the directory
const std::vector<ofFile> & getFiles() const;
/// Access directory contents via th array operator.
///
/// \warning Call listDir() before using this function or the directory
/// contents list will be empty.
/// \throw Throws an out of bounds exception if position >= the number of
/// listed directory contents.
/// \param position array index in the directory contents list
/// \returns opened ofFile instance
ofFile operator[](std::size_t position) const;
/// Check whether hidden files & directories are included when
/// listing files.
///
/// Mac & Linux denote hidden directories by prepending a period
/// -> ".hello".
///
/// \returns true if hidden files are shown
bool getShowHidden() const;
/// Closes the directory.
///
/// This is for backwards compatibility with ofxDirList.
void reset();
/// Sort the directory contents list alphabetically.
///
/// \warning Call listDir() before using this function or there will be
/// nothing to sort.
void sort();
/// Sort the directory contents list by date.
///
/// \warning Call listDir() before using this function or there will be
/// nothing to sort.
void sortByDate();
/// Get a sorted ofDirectory instance using the current path.
///
/// \returns sorted ofDirectory instance
ofDirectory getSorted();
/// Get the number of paths in the current directory list.
///
/// \warning Call listDir() before using this function or it will return 0
/// since the directory list will be empty.
/// \returns number of paths
std::size_t size() const;
OF_DEPRECATED_MSG("Use size() instead.", int numFiles());
// this allows to compare directories by their paths, also provides sorting
// and use as key in stl containers
bool operator==(const ofDirectory & dir) const;
bool operator!=(const ofDirectory & dir) const;
bool operator<(const ofDirectory & dir) const;
bool operator<=(const ofDirectory & dir) const;
bool operator>(const ofDirectory & dir) const;
bool operator>=(const ofDirectory & dir) const;
operator std::filesystem::path(){
return myDir;
}
operator const std::filesystem::path() const{
return myDir;
}
//-------
// static helpers
//-------
/// Create a directory at a given path.
///
/// Creates relative to the data path by default.
///
/// \param dirPath directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data directory
/// \param bRecursive set to true to automatically create nested directories
/// as required
/// \returns true if directory was created successfully
static bool createDirectory(const std::filesystem::path& dirPath, bool bRelativeToData = true, bool recursive = false);
/// Check if a directory at a given path is empty.
///
/// Assumes directory path is relative to the data path by default.
///
/// \param dirPath directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data directory
/// \returns true if the directory is empty aka contains no files or
/// directories
static bool isDirectoryEmpty(const std::filesystem::path& dirPath, bool bRelativeToData = true );
/// Check if a directory exists at a given path.
///
/// Assumes directory path is relative to the data path by default.
///
/// \param dirPath directory path
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data directory
/// \returns true if the directory exists
static bool doesDirectoryExist(const std::filesystem::path& dirPath, bool bRelativeToData = true);
/// remove a directory at a given path
///
/// \param deleteIfNotEmpty set to true if you want to recursively delete
/// the directory *and* its contents
/// \param bRelativeToData set to false if you are working with paths that
/// are *not* in the data directory
/// \returns true if the path was removed successfully
static bool removeDirectory(const std::filesystem::path& path, bool deleteIfNotEmpty, bool bRelativeToData = true);
std::vector<ofFile>::const_iterator begin() const;
std::vector<ofFile>::const_iterator end() const;
std::vector<ofFile>::const_reverse_iterator rbegin() const;
std::vector<ofFile>::const_reverse_iterator rend() const;
private:
std::filesystem::path myDir;
std::string originalDirectory;
std::vector <std::string> extensions;
std::vector <ofFile> files;
bool showHidden;
};
Comments