diff --git a/src/blackmisc/fileutils.cpp b/src/blackmisc/fileutils.cpp index 5cded23bd..d94d1636b 100644 --- a/src/blackmisc/fileutils.cpp +++ b/src/blackmisc/fileutils.cpp @@ -87,4 +87,70 @@ namespace BlackMisc return true; } + QString CFileUtils::findFirstFile(const QDir &dir, bool recursive, const QString &wildcard, std::function predicate) + { + QFileInfoList result = dir.entryInfoList({ wildcard }, QDir::Files); + if (predicate) + { + auto it = std::find_if(result.cbegin(), result.cend(), predicate); + if (it != result.cend()) { return it->filePath(); } + } + else + { + if (! result.isEmpty()) { return result.first().filePath(); } + } + if (recursive) + { + for (const auto &subdir : dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) + { + QString first = findFirstFile(subdir.filePath(), true, wildcard, predicate); + if (! first.isEmpty()) { return first; } + } + } + return {}; + } + + bool CFileUtils::containsFile(const QDir &dir, bool recursive, const QString &wildcard, std::function predicate) + { + return ! findFirstFile(dir, recursive, wildcard, predicate).isEmpty(); + } + + QString CFileUtils::findFirstNewerThan(const QDateTime &time, const QDir &dir, bool recursive, const QString &wildcard) + { + return findFirstFile(dir, recursive, wildcard, [time](const QFileInfo &fi) { return fi.lastModified() > time; }); + } + + bool CFileUtils::containsFileNewerThan(const QDateTime &time, const QDir &dir, bool recursive, const QString &wildcard) + { + return ! findFirstNewerThan(time, dir, recursive, wildcard).isEmpty(); + } + + QFileInfoList CFileUtils::enumerateFiles(const QDir &dir, bool recursive, const QString &wildcard, std::function predicate) + { + QFileInfoList result = dir.entryInfoList({ wildcard }, QDir::Files); + if (predicate) + { + result.erase(std::remove_if(result.begin(), result.end(), std::not1(predicate)), result.end()); + } + if (recursive) + { + for (const auto &subdir : dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) + { + result += enumerateFiles(subdir.filePath(), true, wildcard, predicate); + } + } + return result; + } + + QString CFileUtils::findNewestFile(const QDir &dir, bool recursive, const QString &wildcard) + { + const QFileInfoList files = enumerateFiles(dir, recursive, wildcard); + if (files.isEmpty()) { return {}; } + + auto it = std::max_element(files.cbegin(), files.cend(), [](const QFileInfo &a, const QFileInfo &b) + { + return a.lastModified() < b.lastModified(); + }); + return it->filePath(); + } } // ns diff --git a/src/blackmisc/fileutils.h b/src/blackmisc/fileutils.h index cee630bfa..f62bb9600 100644 --- a/src/blackmisc/fileutils.h +++ b/src/blackmisc/fileutils.h @@ -43,6 +43,24 @@ namespace BlackMisc //! If `sourceDir` is a directory, copies it recursively, so that `sourceDir` becomes `destinationDir`. //! If it is a file, just copies the file. static bool copyRecursively(const QString &sourceDir, const QString &destinationDir); + + //! Returns path to first file in dir which matches the optional wildcard and predicate, or empty string. + static QString findFirstFile(const QDir &dir, bool recursive, const QString &wildcard = {}, std::function predicate = {}); + + //! True if there exists a file in dir which matches the optional wildcard and predicate. + static bool containsFile(const QDir &dir, bool recursive, const QString &wildcard = {}, std::function predicate = {}); + + //! Returns path to first file in dir newer than the given time, optionally matching a wildcard, or empty string. + static QString findFirstNewerThan(const QDateTime &time, const QDir &dir, bool recursive, const QString &wildcard = {}); + + //! True if there exists a file in dir newer than the given time, optionally matching a wildcard. + static bool containsFileNewerThan(const QDateTime &time, const QDir &dir, bool recursive, const QString &wildcard = {}); + + //! Returns list of all files in dir, optionally matching a wildcard and predicate. + static QFileInfoList enumerateFiles(const QDir &dir, bool recursive, const QString &wildcard = {}, std::function predicate = {}); + + //! Returns path to the newest file in dir, optionally matching a wildcard, or empty string. + static QString findNewestFile(const QDir &dir, bool recursive, const QString &wildcard = {}); }; } // ns