Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qdir.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qplatformdefs.h"
5#include "qdir.h"
6#include "qdir_p.h"
8#include "qfsfileengine_p.h"
9#ifndef QT_NO_DEBUG_STREAM
10#include "qdebug.h"
11#endif
12#include "qdirlisting.h"
13#include "qdatetime.h"
14#include "qstring.h"
15#if QT_CONFIG(regularexpression)
16# include <qregularexpression.h>
17#endif
18#include "qvarlengtharray.h"
19#include "qfilesystementry_p.h"
21#include "qfilesystemengine_p.h"
22#include <qstringbuilder.h>
23
24#ifndef QT_BOOTSTRAPPED
25# include <qcollator.h>
26# include "qreadwritelock.h"
27# include "qmutex.h"
28#endif
29
30#include <algorithm>
31#include <memory>
32#include <stdlib.h>
33
35
36using namespace Qt::StringLiterals;
37
38#if defined(Q_OS_WIN)
39static QString driveSpec(const QString &path)
40{
41 if (path.size() < 2)
42 return QString();
43 char c = path.at(0).toLatin1();
44 if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
45 return QString();
46 if (path.at(1).toLatin1() != ':')
47 return QString();
48 return path.mid(0, 2);
49}
50#endif
51
52enum {
53#if defined(Q_OS_WIN)
55#else
56 OSSupportsUncPaths = false
57#endif
58};
59
60// Return the length of the root part of an absolute path, for use by cleanPath(), cd().
61static qsizetype rootLength(QStringView name, bool allowUncPaths)
62{
63 const qsizetype len = name.size();
64 // starts with double slash
65 if (allowUncPaths && name.startsWith("//"_L1)) {
66 // Server name '//server/path' is part of the prefix.
67 const qsizetype nextSlash = name.indexOf(u'/', 2);
68 return nextSlash >= 0 ? nextSlash + 1 : len;
69 }
70#if defined(Q_OS_WIN)
71 if (len >= 2 && name.at(1) == u':') {
72 // Handle a possible drive letter
73 return len > 2 && name.at(2) == u'/' ? 3 : 2;
74 }
75#endif
76 if (name.at(0) == u'/')
77 return 1;
78 return 0;
79}
80
81//************* QDirPrivate
83 QDir::SortFlags sort_, QDir::Filters filters_)
84 : QSharedData(), nameFilters(nameFilters_), sort(sort_), filters(filters_)
85{
86 setPath(path.isEmpty() ? QString::fromLatin1(".") : path);
87
88 auto isEmpty = [](const auto &e) { return e.isEmpty(); };
89 const bool empty = std::all_of(nameFilters.cbegin(), nameFilters.cend(), isEmpty);
90 if (empty)
92}
93
96 // mutex is not copied
97 nameFilters(copy.nameFilters),
98 sort(copy.sort),
100 // fileEngine is not copied
101 dirEntry(copy.dirEntry)
102{
103 QMutexLocker locker(&copy.fileCache.mutex);
104 fileCache.fileListsInitialized = copy.fileCache.fileListsInitialized.load();
105 fileCache.files = copy.fileCache.files;
106 fileCache.fileInfos = copy.fileCache.fileInfos;
107 fileCache.absoluteDirEntry = copy.fileCache.absoluteDirEntry;
108 fileCache.metaData = copy.fileCache.metaData;
109}
110
129
130// static
132{
133 QChar sep(u';');
134 qsizetype i = nameFilter.indexOf(sep, 0);
135 if (i == -1 && nameFilter.indexOf(u' ', 0) != -1)
136 sep = QChar(u' ');
137 return sep;
138}
139
140// static
142{
143 if (sep.isNull())
144 sep = getFilterSepChar(nameFilter);
146 for (auto e : qTokenize(nameFilter, sep))
147 ret.append(e.trimmed().toString());
148 return ret;
149}
150
152{
154 if (p.endsWith(u'/')
155 && p.size() > 1
156#if defined(Q_OS_WIN)
157 && (!(p.length() == 3 && p.at(1).unicode() == ':' && p.at(0).isLetter()))
158#endif
159 ) {
160 p.truncate(p.size() - 1);
161 }
165}
166
168{
172
173 if (dirEntry.isEmpty())
174 return dirEntry.filePath();
175
176 QString absoluteName;
177 if (!fileEngine) {
178 if (!dirEntry.isRelative() && dirEntry.isClean()) {
180 return dirEntry.filePath();
181 }
182
183 absoluteName = QFileSystemEngine::absoluteName(dirEntry).filePath();
184 } else {
185 absoluteName = fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
186 }
187 auto absoluteFileSystemEntry =
189 fileCache.absoluteDirEntry = absoluteFileSystemEntry;
190 return absoluteFileSystemEntry.filePath();
191}
192
193/* For sorting */
195{
196 QDirSortItem() = default;
197 QDirSortItem(const QFileInfo &fi, QDir::SortFlags sort)
198 : item(fi)
199 {
200 // A dir e.g. "dirA.bar" doesn't have actually have an extension/suffix, when
201 // sorting by type such "suffix" should be ignored but that would complicate
202 // the code and uses can change the behavior by setting DirsFirst/DirsLast
203 if (sort.testAnyFlag(QDir::Type))
205 }
206
210};
211
213{
214 QDir::SortFlags qt_cmp_si_sort_flags;
215
216#ifndef QT_BOOTSTRAPPED
217 QCollator *collator = nullptr;
218#endif
219public:
220#ifndef QT_BOOTSTRAPPED
221 QDirSortItemComparator(QDir::SortFlags flags, QCollator *coll = nullptr)
222 : qt_cmp_si_sort_flags(flags), collator(coll)
223 {
224 Q_ASSERT(!qt_cmp_si_sort_flags.testAnyFlag(QDir::LocaleAware) || collator);
225
226 if (collator && qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase))
228 }
229#else
230 QDirSortItemComparator(QDir::SortFlags flags)
231 : qt_cmp_si_sort_flags(flags)
232 {
233 }
234#endif
235 bool operator()(const QDirSortItem &, const QDirSortItem &) const;
236
237 int compareStrings(const QString &a, const QString &b, Qt::CaseSensitivity cs) const
238 {
239#ifndef QT_BOOTSTRAPPED
240 if (collator)
241 return collator->compare(a, b);
242#endif
243 return a.compare(b, cs);
244 }
245};
246
248{
249 const QDirSortItem* f1 = &n1;
250 const QDirSortItem* f2 = &n2;
251
252 if ((qt_cmp_si_sort_flags & QDir::DirsFirst) && (f1->item.isDir() != f2->item.isDir()))
253 return f1->item.isDir();
254 if ((qt_cmp_si_sort_flags & QDir::DirsLast) && (f1->item.isDir() != f2->item.isDir()))
255 return !f1->item.isDir();
256
257 const bool ic = qt_cmp_si_sort_flags.testAnyFlag(QDir::IgnoreCase);
258 const auto qtcase = ic ? Qt::CaseInsensitive : Qt::CaseSensitive;
259
260 qint64 r = 0;
261 int sortBy = ((qt_cmp_si_sort_flags & QDir::SortByMask)
262 | (qt_cmp_si_sort_flags & QDir::Type)).toInt();
263
264 switch (sortBy) {
265 case QDir::Time: {
266 const QDateTime firstModified = f1->item.lastModified(QTimeZone::UTC);
267 const QDateTime secondModified = f2->item.lastModified(QTimeZone::UTC);
268 r = firstModified.msecsTo(secondModified);
269 break;
270 }
271 case QDir::Size:
272 r = f2->item.size() - f1->item.size();
273 break;
274 case QDir::Type:
275 r = compareStrings(f1->suffix_cache, f2->suffix_cache, qtcase);
276 break;
277 default:
278 ;
279 }
280
281 if (r == 0 && sortBy != QDir::Unsorted) {
282 // Still not sorted - sort by name
283
284 if (f1->filename_cache.isNull())
285 f1->filename_cache = f1->item.fileName();
286 if (f2->filename_cache.isNull())
287 f2->filename_cache = f2->item.fileName();
288
289 r = compareStrings(f1->filename_cache, f2->filename_cache, qtcase);
290 }
291 if (qt_cmp_si_sort_flags & QDir::Reversed)
292 return r > 0;
293 return r < 0;
294}
295
296inline void QDirPrivate::sortFileList(QDir::SortFlags sort, const QFileInfoList &l,
298{
299 Q_ASSERT(names || infos);
300 Q_ASSERT(!infos || infos->isEmpty());
301 Q_ASSERT(!names || names->isEmpty());
302
303 const qsizetype n = l.size();
304 if (n == 0)
305 return;
306
307 if (n == 1 || (sort & QDir::SortByMask) == QDir::Unsorted) {
308 if (infos)
309 *infos = l;
310
311 if (names) {
312 for (const QFileInfo &fi : l)
313 names->append(fi.fileName());
314 }
315 } else {
316 QVarLengthArray<QDirSortItem, 64> si;
317 si.reserve(n);
318 for (qsizetype i = 0; i < n; ++i)
319 si.emplace_back(l.at(i), sort);
320
321#ifndef QT_BOOTSTRAPPED
322 if (sort.testAnyFlag(QDir::LocaleAware)) {
323 QCollator coll;
324 std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort, &coll));
325 } else {
326 std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort));
327 }
328#else
329 std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort));
330#endif // QT_BOOTSTRAPPED
331
332 // put them back in the list(s)
333 for (qsizetype i = 0; i < n; ++i) {
334 auto &fileInfo = si[i].item;
335 if (infos)
336 infos->append(fileInfo);
337 if (names) {
338 const bool cached = !si[i].filename_cache.isNull();
339 names->append(cached ? si[i].filename_cache : fileInfo.fileName());
340 }
341 }
342 }
343}
344
345inline void QDirPrivate::initFileLists(const QDir &dir) const
346{
350 for (const auto &dirEntry : QDirListing(dir))
351 l.emplace_back(dirEntry.fileInfo());
352
355 }
356}
357
368
566{
567}
568
576{
577}
578
597QDir::QDir(const QString &path, const QString &nameFilter,
598 SortFlags sort, Filters filters)
599 : d_ptr(new QDirPrivate(path, QDir::nameFiltersFromString(nameFilter), sort, filters))
600{
601}
602
610 : d_ptr(dir.d_ptr)
611{
612}
613
619{
620}
621
639{
641}
642
654{
655 Q_D(const QDir);
656 return d->dirEntry.filePath();
657}
658
668{
669 Q_D(const QDir);
670 if (!d->fileEngine)
671 return d->resolveAbsoluteEntry();
672
673 return d->fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
674}
675
693{
694 Q_D(const QDir);
695 if (!d->fileEngine) {
696 QMutexLocker locker(&d->fileCache.mutex);
697 QFileSystemEntry answer =
698 QFileSystemEngine::canonicalName(d->dirEntry, d->fileCache.metaData);
699 return answer.filePath();
700 }
701 return d->fileEngine->fileName(QAbstractFileEngine::CanonicalName);
702}
703
716{
717 Q_D(const QDir);
718 if (!d_ptr->fileEngine)
719 return d->dirEntry.fileName();
720 return d->fileEngine->fileName(QAbstractFileEngine::BaseName);
721}
722
723
724#ifdef Q_OS_WIN
725static qsizetype drivePrefixLength(QStringView path)
726{
727 // Used to extract path's drive for use as prefix for an "absolute except for drive" path
728 const qsizetype size = path.size();
729 qsizetype drive = 2; // length of drive prefix
730 if (size > 1 && path.at(1).unicode() == ':') {
731 if (Q_UNLIKELY(!path.at(0).isLetter()))
732 return 0;
733 } else if (path.startsWith("//"_L1)) {
734 // UNC path; use its //server/share part as "drive" - it's as sane a
735 // thing as we can do.
736 for (int i = 0 ; i < 2 ; ++i) { // Scan two "path fragments":
737 while (drive < size && path.at(drive).unicode() == '/')
738 drive++;
739 if (drive >= size) {
740 qWarning("Base directory starts with neither a drive nor a UNC share: %s",
742 return 0;
743 }
744 while (drive < size && path.at(drive).unicode() != '/')
745 drive++;
746 }
747 } else {
748 return 0;
749 }
750 return drive;
751}
752#endif // Q_OS_WIN
753
754static bool treatAsAbsolute(const QString &path)
755{
756 // ### Qt 6: be consistent about absolute paths
757
758 // QFileInfo will use the right FS-engine for virtual file-systems
759 // (e.g. resource paths). Unfortunately, for real file-systems, it relies
760 // on QFileSystemEntry's isRelative(), which is flawed on MS-Win, ignoring
761 // its (correct) isAbsolute(). So only use that isAbsolute() unless there's
762 // a colon in the path.
763 // FIXME: relies on virtual file-systems having colons in their prefixes.
764 // The case of an MS-absolute C:/... path happens to work either way.
765 return (path.contains(u':') && QFileInfo(path).isAbsolute())
767}
768
779{
781 return fileName;
782
783 Q_D(const QDir);
784 QString ret = d->dirEntry.filePath();
785 if (fileName.isEmpty())
786 return ret;
787
788#ifdef Q_OS_WIN
789 if (fileName.startsWith(u'/') || fileName.startsWith(u'\\')) {
790 // Handle the "absolute except for drive" case (i.e. \blah not c:\blah):
791 const qsizetype drive = drivePrefixLength(ret);
792 return drive > 0 ? QStringView{ret}.left(drive) % fileName : fileName;
793 }
794#endif // Q_OS_WIN
795
796 if (ret.isEmpty() || ret.endsWith(u'/'))
797 return ret % fileName;
798 return ret % u'/' % fileName;
799}
800
810{
812 return fileName;
813
814 Q_D(const QDir);
815 QString absoluteDirPath = d->resolveAbsoluteEntry();
816 if (fileName.isEmpty())
817 return absoluteDirPath;
818#ifdef Q_OS_WIN
819 // Handle the "absolute except for drive" case (i.e. \blah not c:\blah):
820 if (fileName.startsWith(u'/') || fileName.startsWith(u'\\')) {
821 // Combine absoluteDirPath's drive with fileName
822 const qsizetype drive = drivePrefixLength(absoluteDirPath);
823 if (Q_LIKELY(drive))
824 return QStringView{absoluteDirPath}.left(drive) % fileName;
825
826 qWarning("Base directory's drive is not a letter: %s",
827 qUtf8Printable(QDir::toNativeSeparators(absoluteDirPath)));
828 return QString();
829 }
830#endif // Q_OS_WIN
831 if (!absoluteDirPath.endsWith(u'/'))
832 return absoluteDirPath % u'/' % fileName;
833 return absoluteDirPath % fileName;
834}
835
844{
847
849 return file;
850
851#ifdef Q_OS_WIN
852 QString dirDrive = driveSpec(dir);
853 QString fileDrive = driveSpec(file);
854
855 bool fileDriveMissing = false;
856 if (fileDrive.isEmpty()) {
857 fileDrive = dirDrive;
858 fileDriveMissing = true;
859 }
860
861 if (fileDrive.toLower() != dirDrive.toLower()
862 || (file.startsWith("//"_L1)
863 && !dir.startsWith("//"_L1))) {
864 return file;
865 }
866
867 dir.remove(0, dirDrive.size());
868 if (!fileDriveMissing)
869 file.remove(0, fileDrive.size());
870#endif
871
873 const auto dirElts = dir.tokenize(u'/', Qt::SkipEmptyParts);
874 const auto fileElts = file.tokenize(u'/', Qt::SkipEmptyParts);
875
876 const auto dend = dirElts.end();
877 const auto fend = fileElts.end();
878 auto dit = dirElts.begin();
879 auto fit = fileElts.begin();
880
881 const auto eq = [](QStringView lhs, QStringView rhs) {
882 return
883#if defined(Q_OS_WIN)
884 lhs.compare(rhs, Qt::CaseInsensitive) == 0;
885#else
886 lhs == rhs;
887#endif
888 };
889
890 // std::ranges::mismatch
891 while (dit != dend && fit != fend && eq(*dit, *fit)) {
892 ++dit;
893 ++fit;
894 }
895
896 while (dit != dend) {
897 result += "../"_L1;
898 ++dit;
899 }
900
901 if (fit != fend) {
902 while (fit != fend) {
903 result += *fit++;
904 result += u'/';
905 }
906 result.chop(1);
907 }
908
909 if (result.isEmpty())
910 result = "."_L1;
911 return result;
912}
913
930{
931#if defined(Q_OS_WIN)
932 qsizetype i = pathName.indexOf(u'/');
933 if (i != -1) {
934 QString n(pathName);
935
936 QChar * const data = n.data();
937 data[i++] = u'\\';
938
939 for (; i < n.length(); ++i) {
940 if (data[i] == u'/')
941 data[i] = u'\\';
942 }
943
944 return n;
945 }
946#endif
947 return pathName;
948}
949
963{
964#if defined(Q_OS_WIN)
965 return QFileSystemEntry::removeUncOrLongPathPrefix(pathName).replace(u'\\', u'/');
966#else
967 return pathName;
968#endif
969}
970
971static QString qt_cleanPath(const QString &path, bool *ok = nullptr);
972
984bool QDir::cd(const QString &dirName)
985{
986 // Don't detach just yet.
987 const QDirPrivate * const d = d_ptr.constData();
988
989 if (dirName.isEmpty() || dirName == u'.')
990 return true;
991 QString newPath;
992 if (isAbsolutePath(dirName)) {
993 newPath = qt_cleanPath(dirName);
994 } else {
995 newPath = d->dirEntry.filePath();
996 if (!newPath.endsWith(u'/'))
997 newPath += u'/';
998 newPath += dirName;
999 if (dirName.indexOf(u'/') >= 0
1000 || dirName == ".."_L1
1001 || d->dirEntry.filePath() == u'.') {
1002 bool ok;
1003 newPath = qt_cleanPath(newPath, &ok);
1004 if (!ok)
1005 return false;
1006 /*
1007 If newPath starts with .., we convert it to absolute to
1008 avoid infinite looping on
1009
1010 QDir dir(".");
1011 while (dir.cdUp())
1012 ;
1013 */
1014 if (newPath.startsWith(".."_L1)) {
1015 newPath = QFileInfo(newPath).absoluteFilePath();
1016 }
1017 }
1018 }
1019
1020 std::unique_ptr<QDirPrivate> dir(new QDirPrivate(*d_ptr.constData()));
1021 dir->setPath(newPath);
1022 if (!dir->exists())
1023 return false;
1024
1025 d_ptr = dir.release();
1026 return true;
1027}
1028
1043{
1044 return cd(QString::fromLatin1(".."));
1045}
1046
1051{
1052 Q_D(const QDir);
1053 return d->nameFilters;
1054}
1055
1071void QDir::setNameFilters(const QStringList &nameFilters)
1072{
1073 Q_D(QDir);
1074 d->clearCache(QDirPrivate::KeepMetaData);
1075 d->nameFilters = nameFilters;
1076}
1077
1078#ifndef QT_BOOTSTRAPPED
1079
1080namespace {
1081struct DirSearchPaths {
1082 mutable QReadWriteLock mutex;
1083 QHash<QString, QStringList> paths;
1084};
1085}
1086
1087Q_GLOBAL_STATIC(DirSearchPaths, dirSearchPaths)
1088
1089
1109void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths)
1110{
1111 if (prefix.size() < 2) {
1112 qWarning("QDir::setSearchPaths: Prefix must be longer than 1 character");
1113 return;
1114 }
1115
1116 for (QChar ch : prefix) {
1117 if (!ch.isLetterOrNumber()) {
1118 qWarning("QDir::setSearchPaths: Prefix can only contain letters or numbers");
1119 return;
1120 }
1121 }
1122
1123 DirSearchPaths &conf = *dirSearchPaths;
1124 const QWriteLocker lock(&conf.mutex);
1125 if (searchPaths.isEmpty()) {
1126 conf.paths.remove(prefix);
1127 } else {
1128 conf.paths.insert(prefix, searchPaths);
1129 }
1130}
1131
1139void QDir::addSearchPath(const QString &prefix, const QString &path)
1140{
1141 if (path.isEmpty())
1142 return;
1143
1144 DirSearchPaths &conf = *dirSearchPaths;
1145 const QWriteLocker lock(&conf.mutex);
1146 conf.paths[prefix] += path;
1147}
1148
1157{
1158 if (!dirSearchPaths.exists())
1159 return QStringList();
1160
1161 const DirSearchPaths &conf = *dirSearchPaths;
1162 const QReadLocker lock(&conf.mutex);
1163 return conf.paths.value(prefix);
1164}
1165
1166#endif // QT_BOOTSTRAPPED
1167
1171QDir::Filters QDir::filter() const
1172{
1173 Q_D(const QDir);
1174 return d->filters;
1175}
1176
1251{
1252 Q_D(QDir);
1253 d->clearCache(QDirPrivate::KeepMetaData);
1254 d->filters = filters;
1255}
1256
1262QDir::SortFlags QDir::sorting() const
1263{
1264 Q_D(const QDir);
1265 return d->sort;
1266}
1267
1297#ifndef QT_BOOTSTRAPPED
1306void QDir::setSorting(SortFlags sort)
1307{
1308 Q_D(QDir);
1309 d->clearCache(QDirPrivate::KeepMetaData);
1310 d->sort = sort;
1311}
1312
1324{
1325 Q_D(const QDir);
1326 d->initFileLists(*this);
1327 return d->fileCache.files.size();
1328}
1329
1340{
1341 Q_D(const QDir);
1342 d->initFileLists(*this);
1343 return d->fileCache.files[pos];
1344}
1345
1365QStringList QDir::entryList(Filters filters, SortFlags sort) const
1366{
1367 Q_D(const QDir);
1368 return entryList(d->nameFilters, filters, sort);
1369}
1370
1371
1388QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const
1389{
1390 Q_D(const QDir);
1391 return entryInfoList(d->nameFilters, filters, sort);
1392}
1393
1411 SortFlags sort) const
1412{
1413 Q_D(const QDir);
1414
1415 if (filters == NoFilter)
1416 filters = d->filters;
1417 if (sort == NoSort)
1418 sort = d->sort;
1419
1420 const bool needsSorting = (sort & QDir::SortByMask) != QDir::Unsorted;
1421
1422 if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) {
1423 // Don't fill a QFileInfo cache if we just need names
1424 if (needsSorting || d->fileCache.fileListsInitialized) {
1425 d->initFileLists(*this);
1426 return d->fileCache.files;
1427 }
1428 }
1429
1430 QDirListing dirList(d->dirEntry.filePath(), nameFilters, filters);
1432 if (needsSorting) {
1433 QFileInfoList l;
1434 for (const auto &dirEntry : dirList)
1435 l.emplace_back(dirEntry.fileInfo());
1436 d->sortFileList(sort, l, &ret, nullptr);
1437 } else {
1438 for (const auto &dirEntry : dirList)
1439 ret.emplace_back(dirEntry.fileName());
1440 }
1441 return ret;
1442}
1443
1461 SortFlags sort) const
1462{
1463 Q_D(const QDir);
1464
1465 if (filters == NoFilter)
1466 filters = d->filters;
1467 if (sort == NoSort)
1468 sort = d->sort;
1469
1470 if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) {
1471 d->initFileLists(*this);
1472 return d->fileCache.fileInfos;
1473 }
1474
1475 QFileInfoList l;
1476 for (const auto &dirEntry : QDirListing(d->dirEntry.filePath(), nameFilters, filters))
1477 l.emplace_back(dirEntry.fileInfo());
1479 d->sortFileList(sort, l, nullptr, &ret);
1480 return ret;
1481}
1482#endif // !QT_BOOTSTRAPPED
1483
1504bool QDir::mkdir(const QString &dirName, QFile::Permissions permissions) const
1505{
1506 Q_D(const QDir);
1507
1508 if (dirName.isEmpty()) {
1509 qWarning("QDir::mkdir: Empty or null file name");
1510 return false;
1511 }
1512
1513 QString fn = filePath(dirName);
1514 if (!d->fileEngine)
1515 return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), false, permissions);
1516 return d->fileEngine->mkdir(fn, false, permissions);
1517}
1518
1526bool QDir::mkdir(const QString &dirName) const
1527{
1528 Q_D(const QDir);
1529
1530 if (dirName.isEmpty()) {
1531 qWarning("QDir::mkdir: Empty or null file name");
1532 return false;
1533 }
1534
1535 QString fn = filePath(dirName);
1536 if (!d->fileEngine)
1538 return d->fileEngine->mkdir(fn, false);
1539}
1540
1550bool QDir::rmdir(const QString &dirName) const
1551{
1552 Q_D(const QDir);
1553
1554 if (dirName.isEmpty()) {
1555 qWarning("QDir::rmdir: Empty or null file name");
1556 return false;
1557 }
1558
1559 QString fn = filePath(dirName);
1560 if (!d->fileEngine)
1562
1563 return d->fileEngine->rmdir(fn, false);
1564}
1565
1578bool QDir::mkpath(const QString &dirPath) const
1579{
1580 Q_D(const QDir);
1581
1582 if (dirPath.isEmpty()) {
1583 qWarning("QDir::mkpath: Empty or null file name");
1584 return false;
1585 }
1586
1587 QString fn = filePath(dirPath);
1588 if (!d->fileEngine)
1590 return d->fileEngine->mkdir(fn, true);
1591}
1592
1604bool QDir::rmpath(const QString &dirPath) const
1605{
1606 Q_D(const QDir);
1607
1608 if (dirPath.isEmpty()) {
1609 qWarning("QDir::rmpath: Empty or null file name");
1610 return false;
1611 }
1612
1613 QString fn = filePath(dirPath);
1614 if (!d->fileEngine)
1616 return d->fileEngine->rmdir(fn, true);
1617}
1618
1619#ifndef QT_BOOTSTRAPPED
1641{
1642 if (!d_ptr->exists())
1643 return true;
1644
1645 bool success = true;
1646 const QString dirPath = path();
1647 // not empty -- we must empty it first
1648 constexpr auto dirFilters = QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot;
1649 for (const auto &dirEntry : QDirListing(dirPath, dirFilters)) {
1650 const QString &filePath = dirEntry.filePath();
1651 bool ok;
1652 if (dirEntry.isDir() && !dirEntry.isSymLink()) {
1653 ok = QDir(filePath).removeRecursively(); // recursive
1654 } else {
1656 if (!ok) { // Read-only files prevent directory deletion on Windows, retry with Write permission.
1657 const QFile::Permissions permissions = QFile::permissions(filePath);
1658 if (!(permissions & QFile::WriteUser))
1661 }
1662 }
1663 if (!ok)
1664 success = false;
1665 }
1666
1667 if (success)
1668 success = rmdir(absolutePath());
1669
1670 return success;
1671}
1672#endif // !QT_BOOTSTRAPPED
1673
1684{
1685 Q_D(const QDir);
1686
1687 if (!d->fileEngine) {
1688 QMutexLocker locker(&d->fileCache.mutex);
1689 if (!d->fileCache.metaData.hasFlags(QFileSystemMetaData::UserReadPermission)) {
1690 QFileSystemEngine::fillMetaData(d->dirEntry, d->fileCache.metaData,
1692 }
1693 return d->fileCache.metaData.permissions().testAnyFlag(QFile::ReadUser);
1694 }
1695
1696 const QAbstractFileEngine::FileFlags info =
1697 d->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType
1700 return false;
1701 return info.testAnyFlag(QAbstractFileEngine::ReadUserPerm);
1702}
1703
1715bool QDir::exists() const
1716{
1717 return d_ptr->exists();
1718}
1719
1732bool QDir::isRoot() const
1733{
1734 if (!d_ptr->fileEngine)
1735 return d_ptr->dirEntry.isRoot();
1737}
1738
1774{
1775 if (!d_ptr->fileEngine)
1776 return d_ptr->dirEntry.isRelative();
1777 return d_ptr->fileEngine->isRelativePath();
1778}
1779
1780
1789{
1790 Q_D(const QDir);
1791 std::unique_ptr<QDirPrivate> dir;
1792 if (!!d->fileEngine) {
1795 return false;
1796
1797 dir.reset(new QDirPrivate(*d_ptr.constData()));
1798 dir->setPath(absolutePath);
1799 } else { // native FS
1800 QString absoluteFilePath = d->resolveAbsoluteEntry();
1801 dir.reset(new QDirPrivate(*d_ptr.constData()));
1802 dir->setPath(absoluteFilePath);
1803 }
1804 d_ptr = dir.release(); // actually detach
1805 return true;
1806}
1807
1819bool comparesEqual(const QDir &lhs, const QDir &rhs)
1820{
1821 const QDirPrivate *d = lhs.d_ptr.constData();
1822 const QDirPrivate *other = rhs.d_ptr.constData();
1823
1824 if (d == other)
1825 return true;
1826 Qt::CaseSensitivity sensitive;
1827 if (!d->fileEngine || !other->fileEngine) {
1828 if (d->fileEngine.get() != other->fileEngine.get()) // one is native, the other is a custom file-engine
1829 return false;
1830
1832 } else {
1833 if (d->fileEngine->caseSensitive() != other->fileEngine->caseSensitive())
1834 return false;
1835 sensitive = d->fileEngine->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
1836 }
1837
1838 if (d->filters == other->filters
1839 && d->sort == other->sort
1840 && d->nameFilters == other->nameFilters) {
1841
1842 // Assume directories are the same if path is the same
1843 if (d->dirEntry.filePath() == other->dirEntry.filePath())
1844 return true;
1845
1846 if (lhs.exists()) {
1847 if (!rhs.exists())
1848 return false; //can't be equal if only one exists
1849 // Both exist, fallback to expensive canonical path computation
1850 return lhs.canonicalPath().compare(rhs.canonicalPath(), sensitive) == 0;
1851 } else {
1852 if (rhs.exists())
1853 return false; //can't be equal if only one exists
1854 // Neither exists, compare absolute paths rather than canonical (which would be empty strings)
1855 QString thisFilePath = d->resolveAbsoluteEntry();
1856 QString otherFilePath = other->resolveAbsoluteEntry();
1857 return thisFilePath.compare(otherFilePath, sensitive) == 0;
1858 }
1859 }
1860 return false;
1861}
1862
1868{
1869 d_ptr = dir.d_ptr;
1870 return *this;
1871}
1872
1899{
1900 if (fileName.isEmpty()) {
1901 qWarning("QDir::remove: Empty or null file name");
1902 return false;
1903 }
1905}
1906
1923bool QDir::rename(const QString &oldName, const QString &newName)
1924{
1925 if (oldName.isEmpty() || newName.isEmpty()) {
1926 qWarning("QDir::rename: Empty or null file name(s)");
1927 return false;
1928 }
1929
1930 QFile file(filePath(oldName));
1931 if (!file.exists())
1932 return false;
1933 return file.rename(filePath(newName));
1934}
1935
1946bool QDir::exists(const QString &name) const
1947{
1948 if (name.isEmpty()) {
1949 qWarning("QDir::exists: Empty or null file name");
1950 return false;
1951 }
1953}
1954
1955#ifndef QT_BOOTSTRAPPED
1969bool QDir::isEmpty(Filters filters) const
1970{
1971 Q_D(const QDir);
1972 QDirListing dirList(d->dirEntry.filePath(), d->nameFilters, filters);
1973 return dirList.cbegin() == dirList.cend();
1974}
1975#endif // !QT_BOOTSTRAPPED
1976
1988{
1989#ifdef QT_NO_FSFILEENGINE
1990 return QFileInfoList();
1991#else
1992 return QFSFileEngine::drives();
1993#endif
1994}
1995
2034
2055{
2056 return QFileSystemEngine::currentPath().filePath();
2057}
2058
2107
2137
2163
2164#if QT_CONFIG(regularexpression)
2174bool QDir::match(const QStringList &filters, const QString &fileName)
2175{
2176 for (QStringList::ConstIterator sit = filters.constBegin(); sit != filters.constEnd(); ++sit) {
2177 // Insensitive exact match
2179 if (rx.match(fileName).hasMatch())
2180 return true;
2181 }
2182 return false;
2183}
2184
2193bool QDir::match(const QString &filter, const QString &fileName)
2194{
2196}
2197#endif // QT_CONFIG(regularexpression)
2198
2207QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok)
2208{
2209 const bool allowUncPaths = flags.testAnyFlag(QDirPrivate::AllowUncPaths);
2210 const bool isRemote = flags.testAnyFlag(QDirPrivate::RemotePath);
2211 const qsizetype len = name.size();
2212
2213 if (ok)
2214 *ok = false;
2215
2216 if (len == 0)
2217 return name;
2218
2219 qsizetype i = len - 1;
2220 QVarLengthArray<char16_t> outVector(len);
2221 qsizetype used = len;
2222 char16_t *out = outVector.data();
2223 const char16_t *p = reinterpret_cast<const char16_t *>(name.data());
2224 const char16_t *prefix = p;
2225 qsizetype up = 0;
2226
2227 const qsizetype prefixLength = rootLength(name, allowUncPaths);
2228 p += prefixLength;
2229 i -= prefixLength;
2230
2231 // replicate trailing slash (i > 0 checks for emptiness of input string p)
2232 // except for remote paths because there can be /../ or /./ ending
2233 if (i > 0 && p[i] == '/' && !isRemote) {
2234 out[--used] = '/';
2235 --i;
2236 }
2237
2238 auto isDot = [](const char16_t *p, qsizetype i) {
2239 return i > 1 && p[i - 1] == '.' && p[i - 2] == '/';
2240 };
2241 auto isDotDot = [](const char16_t *p, qsizetype i) {
2242 return i > 2 && p[i - 1] == '.' && p[i - 2] == '.' && p[i - 3] == '/';
2243 };
2244
2245 while (i >= 0) {
2246 // copy trailing slashes for remote urls
2247 if (p[i] == '/') {
2248 if (isRemote && !up) {
2249 if (isDot(p, i)) {
2250 i -= 2;
2251 continue;
2252 }
2253 out[--used] = p[i];
2254 }
2255
2256 --i;
2257 continue;
2258 }
2259
2260 // remove current directory
2261 if (p[i] == '.' && (i == 0 || p[i-1] == '/')) {
2262 --i;
2263 continue;
2264 }
2265
2266 // detect up dir
2267 if (i >= 1 && p[i] == '.' && p[i-1] == '.' && (i < 2 || p[i - 2] == '/')) {
2268 ++up;
2269 i -= i >= 2 ? 3 : 2;
2270
2271 if (isRemote) {
2272 // moving up should consider empty path segments too (/path//../ -> /path/)
2273 while (i > 0 && up && p[i] == '/') {
2274 --up;
2275 --i;
2276 }
2277 }
2278 continue;
2279 }
2280
2281 // prepend a slash before copying when not empty
2282 if (!up && used != len && out[used] != '/')
2283 out[--used] = '/';
2284
2285 // skip or copy
2286 while (i >= 0) {
2287 if (p[i] == '/') {
2288 // copy all slashes as is for remote urls if they are not part of /./ or /../
2289 if (isRemote && !up) {
2290 while (i > 0 && p[i] == '/' && !isDotDot(p, i)) {
2291
2292 if (isDot(p, i)) {
2293 i -= 2;
2294 continue;
2295 }
2296
2297 out[--used] = p[i];
2298 --i;
2299 }
2300
2301 // in case of /./, jump over
2302 if (isDot(p, i))
2303 i -= 2;
2304
2305 break;
2306 }
2307
2308 --i;
2309 break;
2310 }
2311
2312 // actual copy
2313 if (!up)
2314 out[--used] = p[i];
2315 --i;
2316 }
2317
2318 // decrement up after copying/skipping
2319 if (up)
2320 --up;
2321 }
2322
2323 // Indicate failure when ".." are left over for an absolute path.
2324 if (ok)
2325 *ok = prefixLength == 0 || up == 0;
2326
2327 // add remaining '..'
2328 while (up && !isRemote) {
2329 if (used != len && out[used] != '/') // is not empty and there isn't already a '/'
2330 out[--used] = '/';
2331 out[--used] = '.';
2332 out[--used] = '.';
2333 --up;
2334 }
2335
2336 bool isEmpty = used == len;
2337
2338 if (prefixLength) {
2339 if (!isEmpty && out[used] == '/') {
2340 // Even though there is a prefix the out string is a slash. This happens, if the input
2341 // string only consists of a prefix followed by one or more slashes. Just skip the slash.
2342 ++used;
2343 }
2344 for (qsizetype i = prefixLength - 1; i >= 0; --i)
2345 out[--used] = prefix[i];
2346 } else {
2347 if (isEmpty) {
2348 // After resolving the input path, the resulting string is empty (e.g. "foo/.."). Return
2349 // a dot in that case.
2350 out[--used] = '.';
2351 } else if (out[used] == '/') {
2352 // After parsing the input string, out only contains a slash. That happens whenever all
2353 // parts are resolved and there is a trailing slash ("./" or "foo/../" for example).
2354 // Prepend a dot to have the correct return value.
2355 out[--used] = '.';
2356 }
2357 }
2358
2359 // If path was not modified return the original value
2360 if (used == 0)
2361 return name;
2362 return QStringView(out + used, len - used).toString();
2363}
2364
2365static QString qt_cleanPath(const QString &path, bool *ok)
2366{
2367 if (path.isEmpty()) {
2368 Q_ASSERT(!ok); // The only caller passing ok knows its path is non-empty
2369 return path;
2370 }
2371
2374
2375 // Strip away last slash except for root directories
2376 if (ret.size() > 1 && ret.endsWith(u'/')) {
2377#if defined (Q_OS_WIN)
2378 if (!(ret.length() == 3 && ret.at(1) == u':'))
2379#endif
2380 ret.chop(1);
2381 }
2382
2383 return ret;
2384}
2385
2399{
2400 return qt_cleanPath(path);
2401}
2402
2413{
2414 return QFileInfo(path).isRelative();
2415}
2416
2420void QDir::refresh() const
2421{
2422 QDirPrivate *d = const_cast<QDir *>(this)->d_func();
2424}
2425
2429QDirPrivate* QDir::d_func()
2430{
2431 return d_ptr.data();
2432}
2433
2442{
2443 return QDirPrivate::splitFilters(nameFilter);
2444}
2445
2446#ifndef QT_NO_DEBUG_STREAM
2448{
2449 QDebugStateSaver save(debug);
2450 debug.resetFormat();
2452 if (filters == QDir::NoFilter) {
2453 flags << "NoFilter"_L1;
2454 } else {
2455 if (filters & QDir::Dirs) flags << "Dirs"_L1;
2456 if (filters & QDir::AllDirs) flags << "AllDirs"_L1;
2457 if (filters & QDir::Files) flags << "Files"_L1;
2458 if (filters & QDir::Drives) flags << "Drives"_L1;
2459 if (filters & QDir::NoSymLinks) flags << "NoSymLinks"_L1;
2460 if (filters & QDir::NoDot) flags << "NoDot"_L1;
2461 if (filters & QDir::NoDotDot) flags << "NoDotDot"_L1;
2462 if ((filters & QDir::AllEntries) == QDir::AllEntries) flags << "AllEntries"_L1;
2463 if (filters & QDir::Readable) flags << "Readable"_L1;
2464 if (filters & QDir::Writable) flags << "Writable"_L1;
2465 if (filters & QDir::Executable) flags << "Executable"_L1;
2466 if (filters & QDir::Modified) flags << "Modified"_L1;
2467 if (filters & QDir::Hidden) flags << "Hidden"_L1;
2468 if (filters & QDir::System) flags << "System"_L1;
2469 if (filters & QDir::CaseSensitive) flags << "CaseSensitive"_L1;
2470 }
2471 debug.noquote() << "QDir::Filters(" << flags.join(u'|') << ')';
2472 return debug;
2473}
2474
2475static QDebug operator<<(QDebug debug, QDir::SortFlags sorting)
2476{
2477 QDebugStateSaver save(debug);
2478 debug.resetFormat();
2479 if (sorting == QDir::NoSort) {
2480 debug << "QDir::SortFlags(NoSort)";
2481 } else {
2482 QString type;
2483 if ((sorting & QDir::SortByMask) == QDir::Name) type = "Name"_L1;
2484 if ((sorting & QDir::SortByMask) == QDir::Time) type = "Time"_L1;
2485 if ((sorting & QDir::SortByMask) == QDir::Size) type = "Size"_L1;
2486 if ((sorting & QDir::SortByMask) == QDir::Unsorted) type = "Unsorted"_L1;
2487
2489 if (sorting & QDir::DirsFirst) flags << "DirsFirst"_L1;
2490 if (sorting & QDir::DirsLast) flags << "DirsLast"_L1;
2491 if (sorting & QDir::IgnoreCase) flags << "IgnoreCase"_L1;
2492 if (sorting & QDir::LocaleAware) flags << "LocaleAware"_L1;
2493 if (sorting & QDir::Type) flags << "Type"_L1;
2494 debug.noquote() << "QDir::SortFlags(" << type << '|' << flags.join(u'|') << ')';
2495 }
2496 return debug;
2497}
2498
2500{
2501 QDebugStateSaver save(debug);
2502 debug.resetFormat();
2503 debug << "QDir(" << dir.path() << ", nameFilters = {"
2504 << dir.nameFilters().join(u',')
2505 << "}, "
2506 << dir.sorting()
2507 << ','
2508 << dir.filter()
2509 << ')';
2510 return debug;
2511}
2512#endif // QT_NO_DEBUG_STREAM
2513
\inmodule QtCore
\inmodule QtCore
Definition qcollator.h:44
void setCaseSensitivity(Qt::CaseSensitivity cs)
Sets the case-sensitivity of the collator to cs.
int compare(const QString &s1, const QString &s2) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qcollator.h:70
\inmodule QtCore\reentrant
Definition qdatetime.h:283
qint64 msecsTo(const QDateTime &) const
Returns the number of milliseconds from this datetime to the other datetime.
\inmodule QtCore
\inmodule QtCore
The QDirListing class provides an STL-style iterator for directory entries.
Definition qdirlisting.h:18
@ AllowUncPaths
Definition qdir_p.h:32
@ DefaultNormalization
Definition qdir_p.h:31
@ RemotePath
Definition qdir_p.h:33
MetaDataClearing
Definition qdir_p.h:56
@ KeepMetaData
Definition qdir_p.h:56
@ IncludingMetaData
Definition qdir_p.h:56
static QChar getFilterSepChar(const QString &nameFilter)
Definition qdir.cpp:131
std::unique_ptr< QAbstractFileEngine > fileEngine
Definition qdir_p.h:65
void setPath(const QString &path)
Definition qdir.cpp:151
QFileSystemEntry dirEntry
Definition qdir_p.h:67
FileCache fileCache
Definition qdir_p.h:78
QDir::SortFlags sort
Definition qdir_p.h:62
void clearCache(MetaDataClearing mode)
Definition qdir.cpp:358
void initFileLists(const QDir &dir) const
Definition qdir.cpp:345
bool exists() const
Definition qdir.cpp:111
QStringList nameFilters
Definition qdir_p.h:61
static void sortFileList(QDir::SortFlags, const QFileInfoList &, QStringList *, QFileInfoList *)
Definition qdir.cpp:296
QString resolveAbsoluteEntry() const
Definition qdir.cpp:167
QDirPrivate(const QString &path, const QStringList &nameFilters_=QStringList(), QDir::SortFlags sort_=QDir::SortFlags(QDir::Name|QDir::IgnoreCase), QDir::Filters filters_=QDir::AllEntries)
Definition qdir.cpp:82
static QStringList splitFilters(const QString &nameFilter, QChar sep={})
Definition qdir.cpp:141
bool operator()(const QDirSortItem &, const QDirSortItem &) const
Definition qdir.cpp:247
QDirSortItemComparator(QDir::SortFlags flags, QCollator *coll=nullptr)
Definition qdir.cpp:221
int compareStrings(const QString &a, const QString &b, Qt::CaseSensitivity cs) const
Definition qdir.cpp:237
\inmodule QtCore
Definition qdir.h:20
bool mkdir(const QString &dirName) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qdir.cpp:1526
bool remove(const QString &fileName)
Removes the file, fileName.
Definition qdir.cpp:1898
QDir(const QDir &)
Constructs a QDir object that is a copy of the QDir object for directory dir.
Definition qdir.cpp:609
QStringList entryList(Filters filters=NoFilter, SortFlags sort=NoSort) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qdir.cpp:1365
QString operator[](qsizetype) const
Returns the file name at position pos in the list of file names.
Definition qdir.cpp:1339
~QDir()
Destroys the QDir object frees up its resources.
Definition qdir.cpp:618
bool cdUp()
Changes directory by moving one directory up from the QDir's current directory.
Definition qdir.cpp:1042
bool isRelative() const
Returns true if the directory path is relative; otherwise returns false.
Definition qdir.cpp:1773
QString dirName() const
Returns the name of the directory; this is not the same as the path, e.g.
Definition qdir.cpp:715
qsizetype count(QT6_DECL_NEW_OVERLOAD) const
Returns the total number of directories and files in the directory.
Definition qdir.cpp:1323
QDir & operator=(const QDir &)
Move-assigns other to this QDir instance.
Definition qdir.cpp:1867
static bool isAbsolutePath(const QString &path)
Returns true if path is absolute; returns false if it is relative.
Definition qdir.h:184
SortFlags sorting() const
Returns the value set by setSorting()
Definition qdir.cpp:1262
void refresh() const
Refreshes the directory information.
Definition qdir.cpp:2420
static QStringList nameFiltersFromString(const QString &nameFilter)
Definition qdir.cpp:2441
bool removeRecursively()
Definition qdir.cpp:1640
bool rmpath(const QString &dirPath) const
Removes the directory path dirPath.
Definition qdir.cpp:1604
static bool isRelativePath(const QString &path)
Returns true if path is relative; returns false if it is absolute.
Definition qdir.cpp:2412
static QString fromNativeSeparators(const QString &pathName)
Definition qdir.cpp:962
static bool setCurrent(const QString &path)
Sets the application's current working directory to path.
Definition qdir.cpp:2030
QString path() const
Returns the path.
Definition qdir.cpp:653
static QStringList searchPaths(const QString &prefix)
Definition qdir.cpp:1156
bool cd(const QString &dirName)
Changes the QDir's directory to dirName.
Definition qdir.cpp:984
QString canonicalPath() const
Returns the canonical path, i.e.
Definition qdir.cpp:692
bool rename(const QString &oldName, const QString &newName)
Renames a file or directory from oldName to newName, and returns true if successful; otherwise return...
Definition qdir.cpp:1923
QSharedDataPointer< QDirPrivate > d_ptr
Definition qdir.h:240
void setSorting(SortFlags sort)
Sets the sort order used by entryList() and entryInfoList().
Definition qdir.cpp:1306
QString absolutePath() const
Returns the absolute path (a path that starts with "/" or with a drive specification),...
Definition qdir.cpp:667
static void addSearchPath(const QString &prefix, const QString &path)
Definition qdir.cpp:1139
QFileInfoList entryInfoList(Filters filters=NoFilter, SortFlags sort=NoSort) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qdir.cpp:1388
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qdir.cpp:1715
bool mkpath(const QString &dirPath) const
Creates the directory path dirPath.
Definition qdir.cpp:1578
static QFileInfoList drives()
Returns a list of the root directories on this system.
Definition qdir.cpp:1987
static QString tempPath()
Returns the absolute canonical path of the system's temporary directory.
Definition qdir.cpp:2133
QString filePath(const QString &fileName) const
Returns the path name of a file in the directory.
Definition qdir.cpp:778
friend class QDirListing
Definition qdir.h:246
bool makeAbsolute()
Converts the directory path to an absolute path.
Definition qdir.cpp:1788
void setFilter(Filters filter)
Sets the filter used by entryList() and entryInfoList() to filters.
Definition qdir.cpp:1250
static QString cleanPath(const QString &path)
Returns path with directory separators normalized (that is, platform-native separators converted to "...
Definition qdir.cpp:2398
void setPath(const QString &path)
Sets the path of the directory to path.
Definition qdir.cpp:638
void setNameFilters(const QStringList &nameFilters)
Sets the name filters used by entryList() and entryInfoList() to the list of filters specified by nam...
Definition qdir.cpp:1071
QString relativeFilePath(const QString &fileName) const
Returns the path to fileName relative to the directory.
Definition qdir.cpp:843
static QString toNativeSeparators(const QString &pathName)
Definition qdir.cpp:929
QString absoluteFilePath(const QString &fileName) const
Returns the absolute path name of a file in the directory.
Definition qdir.cpp:809
@ Size
Definition qdir.h:52
@ IgnoreCase
Definition qdir.h:58
@ SortByMask
Definition qdir.h:54
@ DirsLast
Definition qdir.h:59
@ Unsorted
Definition qdir.h:53
@ Time
Definition qdir.h:51
@ DirsFirst
Definition qdir.h:56
@ Name
Definition qdir.h:50
@ Type
Definition qdir.h:61
@ NoSort
Definition qdir.h:62
@ Reversed
Definition qdir.h:57
@ LocaleAware
Definition qdir.h:60
bool isReadable() const
Returns true if the directory is readable and we can open files by name; otherwise returns false.
Definition qdir.cpp:1683
static QString homePath()
Returns the absolute path of the user's home directory.
Definition qdir.cpp:2103
bool isEmpty(Filters filters=Filters(AllEntries|NoDotAndDotDot)) const
Returns whether the directory is empty.
Definition qdir.cpp:1969
bool isRoot() const
Returns true if the directory is the root directory; otherwise returns false.
Definition qdir.cpp:1732
static QString currentPath()
Returns the absolute path of the application's current directory.
Definition qdir.cpp:2054
static QString rootPath()
Returns the absolute path of the root directory.
Definition qdir.cpp:2159
Filters filter() const
Returns the value set by setFilter()
Definition qdir.cpp:1171
bool rmdir(const QString &dirName) const
Removes the directory specified by dirName.
Definition qdir.cpp:1550
QStringList nameFilters() const
Returns the string list set by setNameFilters()
Definition qdir.cpp:1050
@ Executable
Definition qdir.h:31
@ CaseSensitive
Definition qdir.h:41
@ Files
Definition qdir.h:23
@ Modified
Definition qdir.h:34
@ Hidden
Definition qdir.h:35
@ AllEntries
Definition qdir.h:26
@ Drives
Definition qdir.h:24
@ AllDirs
Definition qdir.h:40
@ NoSymLinks
Definition qdir.h:25
@ NoDotDot
Definition qdir.h:43
@ NoFilter
Definition qdir.h:46
@ Readable
Definition qdir.h:29
@ Writable
Definition qdir.h:30
@ System
Definition qdir.h:36
@ NoDotAndDotDot
Definition qdir.h:44
@ NoDot
Definition qdir.h:42
@ Dirs
Definition qdir.h:22
static QFileInfoList drives()
For Windows, returns the list of drives in the file system as a list of QFileInfo objects.
QString suffix() const
Returns the suffix (extension) of the file.
QString absoluteFilePath() const
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
bool isRelative() const
Returns true if the file system entry's path is relative, otherwise returns false (that is,...
bool exists() const
Returns true if the file system entry this QFileInfo refers to exists; otherwise returns false.
static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data)
static bool setCurrentPath(const QFileSystemEntry &entry)
static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data, QFileSystemMetaData::MetaDataFlags what)
static bool createDirectory(const QFileSystemEntry &entry, bool createParents, std::optional< QFile::Permissions > permissions=std::nullopt)
static std::unique_ptr< QAbstractFileEngine > createLegacyEngine(QFileSystemEntry &entry, QFileSystemMetaData &data)
static QFileSystemEntry absoluteName(const QFileSystemEntry &entry)
static bool isCaseSensitive()
static bool removeDirectory(const QFileSystemEntry &entry, bool removeEmptyParents)
static QFileSystemEntry currentPath()
Q_AUTOTEST_EXPORT bool isEmpty() const
Q_AUTOTEST_EXPORT bool isClean() const
Q_AUTOTEST_EXPORT bool isRelative() const
Q_AUTOTEST_EXPORT bool isRoot() const
Q_AUTOTEST_EXPORT QString filePath() const
Q_AUTOTEST_EXPORT bool isAbsolute() const
\inmodule QtCore
Definition qfile.h:93
bool setPermissions(Permissions permissionSpec) override
Sets the permissions for the file to the permissions specified.
Definition qfile.cpp:1159
bool remove()
Removes the file specified by fileName().
Definition qfile.cpp:419
Permissions permissions() const override
\reimp
Definition qfile.cpp:1130
bool rename(const QString &newName)
Renames the file currently specified by fileName() to newName.
Definition qfile.cpp:554
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qfile.cpp:351
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
reference emplace_back(Args &&... args)
Definition qlist.h:683
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
const_iterator ConstIterator
Definition qlist.h:250
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
\inmodule QtCore
static QRegularExpression fromWildcard(QStringView pattern, Qt::CaseSensitivity cs=Qt::CaseInsensitive, WildcardConversionOptions options=DefaultWildcardConversion)
const T * constData() const noexcept
Returns a const pointer to the shared data object.
Definition qshareddata.h:51
T * data()
Returns a pointer to the shared data object.
Definition qshareddata.h:47
\inmodule QtCore
Definition qshareddata.h:19
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
constexpr void chop(qsizetype n) noexcept
Truncates this string view by length characters.
constexpr QStringView left(qsizetype n) const noexcept
QString toString() const
Returns a deep copy of this string view's data as a QString.
Definition qstring.h:1121
int compare(QStringView other, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
qsizetype indexOf(QLatin1StringView s, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4517
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5455
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6340
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.cpp:6664
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition qstring.cpp:3466
auto tokenize(Needle &&needle, Flags...flags) const &noexcept(noexcept(qTokenize(std::declval< const QString & >(), std::forward< Needle >(needle), flags...))) -> decltype(qTokenize(*this, std::forward< Needle >(needle), flags...))
Definition qstring.h:599
\inmodule QtCore
Combined button and popup list for selecting options.
CaseSensitivity
@ CaseInsensitive
@ CaseSensitive
@ SkipEmptyParts
Definition qnamespace.h:128
static jboolean copy(JNIEnv *, jobject)
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
QList< QString > QStringList
Constructs a string list that contains the given string, str.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
static qsizetype rootLength(QStringView name, bool allowUncPaths)
Definition qdir.cpp:61
QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2447
@ OSSupportsUncPaths
Definition qdir.cpp:56
bool comparesEqual(const QDir &lhs, const QDir &rhs)
Definition qdir.cpp:1819
static QString qt_cleanPath(const QString &path, bool *ok=nullptr)
Definition qdir.cpp:2365
static bool treatAsAbsolute(const QString &path)
Definition qdir.cpp:754
QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok)
Definition qdir.cpp:2207
QList< QFileInfo > QFileInfoList
Definition qfileinfo.h:189
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
return ret
GLboolean GLboolean GLboolean b
GLenum mode
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLsizei const GLuint * paths
GLbitfield flags
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint name
GLfloat n
const GLubyte * c
GLuint GLuint * names
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLenum GLsizei len
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static constexpr QChar sep
#define qUtf8Printable(string)
Definition qstring.h:1535
constexpr auto qTokenize(Haystack &&h, Needle &&n, Flags...flags) noexcept(QtPrivate::Tok::is_nothrow_constructible_from< Haystack, Needle >::value) -> decltype(QtPrivate::Tok::TokenizerResult< Haystack, Needle >{std::forward< Haystack >(h), std::forward< Needle >(n), flags...})
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
#define QT6_IMPL_NEW_OVERLOAD
ptrdiff_t qsizetype
Definition qtypes.h:165
long long qint64
Definition qtypes.h:60
static int toInt(const QChar &qc, int R)
QFile file
[0]
QTextStream out(stdout)
[7]
QMutex mutex
[2]
QReadWriteLock lock
[0]
p rx()++
QSharedPointer< T > other(t)
[5]
QString dir
[11]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
QHostInfo info
[0]
QStringList files
Definition qdir_p.h:72
std::atomic< bool > fileListsInitialized
Definition qdir_p.h:74
QFileSystemEntry absoluteDirEntry
Definition qdir_p.h:75
QFileSystemMetaData metaData
Definition qdir_p.h:76
QFileInfoList fileInfos
Definition qdir_p.h:73
QFileInfo item
Definition qdir.cpp:209
QString suffix_cache
Definition qdir.cpp:208
QDirSortItem(const QFileInfo &fi, QDir::SortFlags sort)
Definition qdir.cpp:197
QDirSortItem()=default
QString filename_cache
Definition qdir.cpp:207