Qt 6.x
The Qt SDK
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 "qdiriterator.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
112{
113 if (!fileEngine) {
118 | QFileSystemMetaData::DirectoryType); // always stat
120 }
121 const QAbstractFileEngine::FileFlags info =
126 return false;
127 return info.testAnyFlag(QAbstractFileEngine::ExistsFlag);
128}
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
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)
314 }
315 } else {
317 for (qsizetype i = 0; i < n; ++i)
318 si[i] = QDirSortItem{l.at(i), sort};
319
320#ifndef QT_BOOTSTRAPPED
321 if (sort.testAnyFlag(QDir::LocaleAware)) {
322 QCollator coll;
323 std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort, &coll));
324 } else {
325 std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort));
326 }
327#else
328 std::sort(si.data(), si.data() + n, QDirSortItemComparator(sort));
329#endif // QT_BOOTSTRAPPED
330
331 // put them back in the list(s)
332 for (qsizetype i = 0; i < n; ++i) {
333 auto &fileInfo = si[i].item;
334 if (infos)
335 infos->append(fileInfo);
336 if (names) {
337 const bool cached = !si[i].filename_cache.isNull();
338 names->append(cached ? si[i].filename_cache : fileInfo.fileName());
339 }
340 }
341 }
342}
343
344inline void QDirPrivate::initFileLists(const QDir &dir) const
345{
350 while (it.hasNext())
351 l.append(it.nextFileInfo());
352
355 }
356}
357
359{
361 if (mode == IncludingMetaData)
364 fileCache.files.clear();
366 fileEngine.reset(
368}
369
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;
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
1305void QDir::setSorting(SortFlags sort)
1306{
1307 Q_D(QDir);
1308 d->clearCache(QDirPrivate::KeepMetaData);
1309 d->sort = sort;
1310}
1311
1323{
1324 Q_D(const QDir);
1325 d->initFileLists(*this);
1326 return d->fileCache.files.size();
1327}
1328
1339{
1340 Q_D(const QDir);
1341 d->initFileLists(*this);
1342 return d->fileCache.files[pos];
1343}
1344
1364QStringList QDir::entryList(Filters filters, SortFlags sort) const
1365{
1366 Q_D(const QDir);
1367 return entryList(d->nameFilters, filters, sort);
1368}
1369
1370
1387QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const
1388{
1389 Q_D(const QDir);
1390 return entryInfoList(d->nameFilters, filters, sort);
1391}
1392
1410 SortFlags sort) const
1411{
1412 Q_D(const QDir);
1413
1414 if (filters == NoFilter)
1415 filters = d->filters;
1416 if (sort == NoSort)
1417 sort = d->sort;
1418
1419 const bool needsSorting = (sort & QDir::SortByMask) != QDir::Unsorted;
1420
1421 if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) {
1422 // Don't fill a QFileInfo cache if we just need names
1423 if (needsSorting || d->fileCache.fileListsInitialized) {
1424 d->initFileLists(*this);
1425 return d->fileCache.files;
1426 }
1427 }
1428
1429 QDirIterator it(d->dirEntry.filePath(), nameFilters, filters);
1431 if (needsSorting) {
1432 QFileInfoList l;
1433 while (it.hasNext())
1434 l.append(it.nextFileInfo());
1435 d->sortFileList(sort, l, &ret, nullptr);
1436 } else {
1437 while (it.hasNext()) {
1438 it.next();
1439 ret.append(it.fileName());
1440 }
1441 }
1442 return ret;
1443}
1444
1462 SortFlags sort) const
1463{
1464 Q_D(const QDir);
1465
1466 if (filters == NoFilter)
1467 filters = d->filters;
1468 if (sort == NoSort)
1469 sort = d->sort;
1470
1471 if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) {
1472 d->initFileLists(*this);
1473 return d->fileCache.fileInfos;
1474 }
1475
1476 QFileInfoList l;
1477 QDirIterator it(d->dirEntry.filePath(), nameFilters, filters);
1478 while (it.hasNext())
1479 l.append(it.nextFileInfo());
1481 d->sortFileList(sort, l, nullptr, &ret);
1482 return ret;
1483}
1484
1505bool QDir::mkdir(const QString &dirName, QFile::Permissions permissions) const
1506{
1507 Q_D(const QDir);
1508
1509 if (dirName.isEmpty()) {
1510 qWarning("QDir::mkdir: Empty or null file name");
1511 return false;
1512 }
1513
1514 QString fn = filePath(dirName);
1515 if (!d->fileEngine)
1516 return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), false, permissions);
1517 return d->fileEngine->mkdir(fn, false, permissions);
1518}
1519
1527bool QDir::mkdir(const QString &dirName) const
1528{
1529 Q_D(const QDir);
1530
1531 if (dirName.isEmpty()) {
1532 qWarning("QDir::mkdir: Empty or null file name");
1533 return false;
1534 }
1535
1536 QString fn = filePath(dirName);
1537 if (!d->fileEngine)
1539 return d->fileEngine->mkdir(fn, false);
1540}
1541
1551bool QDir::rmdir(const QString &dirName) const
1552{
1553 Q_D(const QDir);
1554
1555 if (dirName.isEmpty()) {
1556 qWarning("QDir::rmdir: Empty or null file name");
1557 return false;
1558 }
1559
1560 QString fn = filePath(dirName);
1561 if (!d->fileEngine)
1563
1564 return d->fileEngine->rmdir(fn, false);
1565}
1566
1579bool QDir::mkpath(const QString &dirPath) const
1580{
1581 Q_D(const QDir);
1582
1583 if (dirPath.isEmpty()) {
1584 qWarning("QDir::mkpath: Empty or null file name");
1585 return false;
1586 }
1587
1588 QString fn = filePath(dirPath);
1589 if (!d->fileEngine)
1591 return d->fileEngine->mkdir(fn, true);
1592}
1593
1605bool QDir::rmpath(const QString &dirPath) const
1606{
1607 Q_D(const QDir);
1608
1609 if (dirPath.isEmpty()) {
1610 qWarning("QDir::rmpath: Empty or null file name");
1611 return false;
1612 }
1613
1614 QString fn = filePath(dirPath);
1615 if (!d->fileEngine)
1617 return d->fileEngine->rmdir(fn, true);
1618}
1619
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
1649 while (di.hasNext()) {
1650 const QFileInfo fi = di.nextFileInfo();
1651 const QString &filePath = di.filePath();
1652 bool ok;
1653 if (fi.isDir() && !fi.isSymLink()) {
1654 ok = QDir(filePath).removeRecursively(); // recursive
1655 } else {
1657 if (!ok) { // Read-only files prevent directory deletion on Windows, retry with Write permission.
1658 const QFile::Permissions permissions = QFile::permissions(filePath);
1659 if (!(permissions & QFile::WriteUser))
1662 }
1663 }
1664 if (!ok)
1665 success = false;
1666 }
1667
1668 if (success)
1669 success = rmdir(absolutePath());
1670
1671 return success;
1672}
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
1817bool QDir::operator==(const QDir &dir) const
1818{
1819 Q_D(const QDir);
1820 const QDirPrivate *other = dir.d_ptr.constData();
1821
1822 if (d == other)
1823 return true;
1824 Qt::CaseSensitivity sensitive;
1825 if (!d->fileEngine || !other->fileEngine) {
1826 if (d->fileEngine.get() != other->fileEngine.get()) // one is native, the other is a custom file-engine
1827 return false;
1828
1830 } else {
1831 if (d->fileEngine->caseSensitive() != other->fileEngine->caseSensitive())
1832 return false;
1833 sensitive = d->fileEngine->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
1834 }
1835
1836 if (d->filters == other->filters
1837 && d->sort == other->sort
1838 && d->nameFilters == other->nameFilters) {
1839
1840 // Assume directories are the same if path is the same
1841 if (d->dirEntry.filePath() == other->dirEntry.filePath())
1842 return true;
1843
1844 if (exists()) {
1845 if (!dir.exists())
1846 return false; //can't be equal if only one exists
1847 // Both exist, fallback to expensive canonical path computation
1848 return canonicalPath().compare(dir.canonicalPath(), sensitive) == 0;
1849 } else {
1850 if (dir.exists())
1851 return false; //can't be equal if only one exists
1852 // Neither exists, compare absolute paths rather than canonical (which would be empty strings)
1853 QString thisFilePath = d->resolveAbsoluteEntry();
1854 QString otherFilePath = other->resolveAbsoluteEntry();
1855 return thisFilePath.compare(otherFilePath, sensitive) == 0;
1856 }
1857 }
1858 return false;
1859}
1860
1866{
1867 d_ptr = dir.d_ptr;
1868 return *this;
1869}
1870
1898{
1899 if (fileName.isEmpty()) {
1900 qWarning("QDir::remove: Empty or null file name");
1901 return false;
1902 }
1904}
1905
1922bool QDir::rename(const QString &oldName, const QString &newName)
1923{
1924 if (oldName.isEmpty() || newName.isEmpty()) {
1925 qWarning("QDir::rename: Empty or null file name(s)");
1926 return false;
1927 }
1928
1929 QFile file(filePath(oldName));
1930 if (!file.exists())
1931 return false;
1932 return file.rename(filePath(newName));
1933}
1934
1945bool QDir::exists(const QString &name) const
1946{
1947 if (name.isEmpty()) {
1948 qWarning("QDir::exists: Empty or null file name");
1949 return false;
1950 }
1952}
1953
1967bool QDir::isEmpty(Filters filters) const
1968{
1969 Q_D(const QDir);
1970 QDirIterator it(d->dirEntry.filePath(), d->nameFilters, filters);
1971 return !it.hasNext();
1972}
1973
1985{
1986#ifdef QT_NO_FSFILEENGINE
1987 return QFileInfoList();
1988#else
1989 return QFSFileEngine::drives();
1990#endif
1991}
1992
2028{
2030}
2031
2052{
2054}
2055
2101{
2103}
2104
2131{
2133}
2134
2157{
2159}
2160
2161#if QT_CONFIG(regularexpression)
2171bool QDir::match(const QStringList &filters, const QString &fileName)
2172{
2173 for (QStringList::ConstIterator sit = filters.constBegin(); sit != filters.constEnd(); ++sit) {
2174 // Insensitive exact match
2176 if (rx.match(fileName).hasMatch())
2177 return true;
2178 }
2179 return false;
2180}
2181
2190bool QDir::match(const QString &filter, const QString &fileName)
2191{
2193}
2194#endif // QT_CONFIG(regularexpression)
2195
2204QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok)
2205{
2206 const bool allowUncPaths = flags.testAnyFlag(QDirPrivate::AllowUncPaths);
2207 const bool isRemote = flags.testAnyFlag(QDirPrivate::RemotePath);
2208 const qsizetype len = name.size();
2209
2210 if (ok)
2211 *ok = false;
2212
2213 if (len == 0)
2214 return name;
2215
2216 qsizetype i = len - 1;
2217 QVarLengthArray<char16_t> outVector(len);
2218 qsizetype used = len;
2219 char16_t *out = outVector.data();
2220 const char16_t *p = reinterpret_cast<const char16_t *>(name.data());
2221 const char16_t *prefix = p;
2222 qsizetype up = 0;
2223
2224 const qsizetype prefixLength = rootLength(name, allowUncPaths);
2225 p += prefixLength;
2226 i -= prefixLength;
2227
2228 // replicate trailing slash (i > 0 checks for emptiness of input string p)
2229 // except for remote paths because there can be /../ or /./ ending
2230 if (i > 0 && p[i] == '/' && !isRemote) {
2231 out[--used] = '/';
2232 --i;
2233 }
2234
2235 auto isDot = [](const char16_t *p, qsizetype i) {
2236 return i > 1 && p[i - 1] == '.' && p[i - 2] == '/';
2237 };
2238 auto isDotDot = [](const char16_t *p, qsizetype i) {
2239 return i > 2 && p[i - 1] == '.' && p[i - 2] == '.' && p[i - 3] == '/';
2240 };
2241
2242 while (i >= 0) {
2243 // copy trailing slashes for remote urls
2244 if (p[i] == '/') {
2245 if (isRemote && !up) {
2246 if (isDot(p, i)) {
2247 i -= 2;
2248 continue;
2249 }
2250 out[--used] = p[i];
2251 }
2252
2253 --i;
2254 continue;
2255 }
2256
2257 // remove current directory
2258 if (p[i] == '.' && (i == 0 || p[i-1] == '/')) {
2259 --i;
2260 continue;
2261 }
2262
2263 // detect up dir
2264 if (i >= 1 && p[i] == '.' && p[i-1] == '.' && (i < 2 || p[i - 2] == '/')) {
2265 ++up;
2266 i -= i >= 2 ? 3 : 2;
2267
2268 if (isRemote) {
2269 // moving up should consider empty path segments too (/path//../ -> /path/)
2270 while (i > 0 && up && p[i] == '/') {
2271 --up;
2272 --i;
2273 }
2274 }
2275 continue;
2276 }
2277
2278 // prepend a slash before copying when not empty
2279 if (!up && used != len && out[used] != '/')
2280 out[--used] = '/';
2281
2282 // skip or copy
2283 while (i >= 0) {
2284 if (p[i] == '/') {
2285 // copy all slashes as is for remote urls if they are not part of /./ or /../
2286 if (isRemote && !up) {
2287 while (i > 0 && p[i] == '/' && !isDotDot(p, i)) {
2288
2289 if (isDot(p, i)) {
2290 i -= 2;
2291 continue;
2292 }
2293
2294 out[--used] = p[i];
2295 --i;
2296 }
2297
2298 // in case of /./, jump over
2299 if (isDot(p, i))
2300 i -= 2;
2301
2302 break;
2303 }
2304
2305 --i;
2306 break;
2307 }
2308
2309 // actual copy
2310 if (!up)
2311 out[--used] = p[i];
2312 --i;
2313 }
2314
2315 // decrement up after copying/skipping
2316 if (up)
2317 --up;
2318 }
2319
2320 // Indicate failure when ".." are left over for an absolute path.
2321 if (ok)
2322 *ok = prefixLength == 0 || up == 0;
2323
2324 // add remaining '..'
2325 while (up && !isRemote) {
2326 if (used != len && out[used] != '/') // is not empty and there isn't already a '/'
2327 out[--used] = '/';
2328 out[--used] = '.';
2329 out[--used] = '.';
2330 --up;
2331 }
2332
2333 bool isEmpty = used == len;
2334
2335 if (prefixLength) {
2336 if (!isEmpty && out[used] == '/') {
2337 // Even though there is a prefix the out string is a slash. This happens, if the input
2338 // string only consists of a prefix followed by one or more slashes. Just skip the slash.
2339 ++used;
2340 }
2341 for (qsizetype i = prefixLength - 1; i >= 0; --i)
2342 out[--used] = prefix[i];
2343 } else {
2344 if (isEmpty) {
2345 // After resolving the input path, the resulting string is empty (e.g. "foo/.."). Return
2346 // a dot in that case.
2347 out[--used] = '.';
2348 } else if (out[used] == '/') {
2349 // After parsing the input string, out only contains a slash. That happens whenever all
2350 // parts are resolved and there is a trailing slash ("./" or "foo/../" for example).
2351 // Prepend a dot to have the correct return value.
2352 out[--used] = '.';
2353 }
2354 }
2355
2356 // If path was not modified return the original value
2357 if (used == 0)
2358 return name;
2359 return QString::fromUtf16(out + used, len - used);
2360}
2361
2362static QString qt_cleanPath(const QString &path, bool *ok)
2363{
2364 if (path.isEmpty()) {
2365 Q_ASSERT(!ok); // The only caller passing ok knows its path is non-empty
2366 return path;
2367 }
2368
2371
2372 // Strip away last slash except for root directories
2373 if (ret.size() > 1 && ret.endsWith(u'/')) {
2374#if defined (Q_OS_WIN)
2375 if (!(ret.length() == 3 && ret.at(1) == u':'))
2376#endif
2377 ret.chop(1);
2378 }
2379
2380 return ret;
2381}
2382
2396{
2397 return qt_cleanPath(path);
2398}
2399
2410{
2411 return QFileInfo(path).isRelative();
2412}
2413
2417void QDir::refresh() const
2418{
2419 QDirPrivate *d = const_cast<QDir *>(this)->d_func();
2420 d->clearCache(QDirPrivate::IncludingMetaData);
2421}
2422
2426QDirPrivate* QDir::d_func()
2427{
2428 return d_ptr.data();
2429}
2430
2439{
2440 return QDirPrivate::splitFilters(nameFilter);
2441}
2442
2443#ifndef QT_NO_DEBUG_STREAM
2445{
2446 QDebugStateSaver save(debug);
2447 debug.resetFormat();
2449 if (filters == QDir::NoFilter) {
2450 flags << "NoFilter"_L1;
2451 } else {
2452 if (filters & QDir::Dirs) flags << "Dirs"_L1;
2453 if (filters & QDir::AllDirs) flags << "AllDirs"_L1;
2454 if (filters & QDir::Files) flags << "Files"_L1;
2455 if (filters & QDir::Drives) flags << "Drives"_L1;
2456 if (filters & QDir::NoSymLinks) flags << "NoSymLinks"_L1;
2457 if (filters & QDir::NoDot) flags << "NoDot"_L1;
2458 if (filters & QDir::NoDotDot) flags << "NoDotDot"_L1;
2459 if ((filters & QDir::AllEntries) == QDir::AllEntries) flags << "AllEntries"_L1;
2460 if (filters & QDir::Readable) flags << "Readable"_L1;
2461 if (filters & QDir::Writable) flags << "Writable"_L1;
2462 if (filters & QDir::Executable) flags << "Executable"_L1;
2463 if (filters & QDir::Modified) flags << "Modified"_L1;
2464 if (filters & QDir::Hidden) flags << "Hidden"_L1;
2465 if (filters & QDir::System) flags << "System"_L1;
2466 if (filters & QDir::CaseSensitive) flags << "CaseSensitive"_L1;
2467 }
2468 debug.noquote() << "QDir::Filters(" << flags.join(u'|') << ')';
2469 return debug;
2470}
2471
2472static QDebug operator<<(QDebug debug, QDir::SortFlags sorting)
2473{
2474 QDebugStateSaver save(debug);
2475 debug.resetFormat();
2476 if (sorting == QDir::NoSort) {
2477 debug << "QDir::SortFlags(NoSort)";
2478 } else {
2479 QString type;
2480 if ((sorting & QDir::SortByMask) == QDir::Name) type = "Name"_L1;
2481 if ((sorting & QDir::SortByMask) == QDir::Time) type = "Time"_L1;
2482 if ((sorting & QDir::SortByMask) == QDir::Size) type = "Size"_L1;
2483 if ((sorting & QDir::SortByMask) == QDir::Unsorted) type = "Unsorted"_L1;
2484
2486 if (sorting & QDir::DirsFirst) flags << "DirsFirst"_L1;
2487 if (sorting & QDir::DirsLast) flags << "DirsLast"_L1;
2488 if (sorting & QDir::IgnoreCase) flags << "IgnoreCase"_L1;
2489 if (sorting & QDir::LocaleAware) flags << "LocaleAware"_L1;
2490 if (sorting & QDir::Type) flags << "Type"_L1;
2491 debug.noquote() << "QDir::SortFlags(" << type << '|' << flags.join(u'|') << ')';
2492 }
2493 return debug;
2494}
2495
2497{
2498 QDebugStateSaver save(debug);
2499 debug.resetFormat();
2500 debug << "QDir(" << dir.path() << ", nameFilters = {"
2501 << dir.nameFilters().join(u',')
2502 << "}, "
2503 << dir.sorting()
2504 << ','
2505 << dir.filter()
2506 << ')';
2507 return debug;
2508}
2509#endif // QT_NO_DEBUG_STREAM
2510
\inmodule QtCore
Definition qchar.h:48
constexpr bool isNull() const noexcept
Returns true if the character is the Unicode character 0x0000 ('\0'); otherwise returns false.
Definition qchar.h:463
\inmodule QtCore
Definition qcollator.h:42
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:68
\inmodule QtCore\reentrant
Definition qdatetime.h:257
qint64 msecsTo(const QDateTime &) const
Returns the number of milliseconds from this datetime to the other datetime.
\inmodule QtCore
\inmodule QtCore
The QDirIterator class provides an iterator for directory entrylists.
bool hasNext() const
Returns true if there is at least one more entry in the directory; otherwise, false is returned.
QFileInfo nextFileInfo()
QString filePath() const
Returns the full file path for the current directory entry.
@ 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:344
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:19
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:1527
bool remove(const QString &fileName)
Removes the file, fileName.
Definition qdir.cpp:1897
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:1364
QString operator[](qsizetype) const
Returns the file name at position pos in the list of file names.
Definition qdir.cpp:1338
~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
bool operator==(const QDir &dir) const
Returns true if directory dir and this directory have the same path and their sort and filter setting...
Definition qdir.cpp:1817
qsizetype count(QT6_DECL_NEW_OVERLOAD) const
Returns the total number of directories and files in the directory.
Definition qdir.cpp:1322
QDir & operator=(const QDir &)
Move-assigns other to this QDir instance.
Definition qdir.cpp:1865
static bool isAbsolutePath(const QString &path)
Returns true if path is absolute; returns false if it is relative.
Definition qdir.h:183
SortFlags sorting() const
Returns the value set by setSorting()
Definition qdir.cpp:1262
void refresh() const
Refreshes the directory information.
Definition qdir.cpp:2417
static QStringList nameFiltersFromString(const QString &nameFilter)
Definition qdir.cpp:2438
bool removeRecursively()
Definition qdir.cpp:1640
bool rmpath(const QString &dirPath) const
Removes the directory path dirPath.
Definition qdir.cpp:1605
static bool isRelativePath(const QString &path)
Returns true if path is relative; returns false if it is absolute.
Definition qdir.cpp:2409
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:2027
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:1922
QSharedDataPointer< QDirPrivate > d_ptr
Definition qdir.h:237
void setSorting(SortFlags sort)
Sets the sort order used by entryList() and entryInfoList().
Definition qdir.cpp:1305
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:1387
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:1579
static QFileInfoList drives()
Returns a list of the root directories on this system.
Definition qdir.cpp:1984
static QString tempPath()
Returns the absolute canonical path of the system's temporary directory.
Definition qdir.cpp:2130
QString filePath(const QString &fileName) const
Returns the path name of a file in the directory.
Definition qdir.cpp:778
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:2395
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:51
@ IgnoreCase
Definition qdir.h:57
@ SortByMask
Definition qdir.h:53
@ DirsLast
Definition qdir.h:58
@ Unsorted
Definition qdir.h:52
@ Time
Definition qdir.h:50
@ DirsFirst
Definition qdir.h:55
@ Name
Definition qdir.h:49
@ Type
Definition qdir.h:60
@ NoSort
Definition qdir.h:61
@ Reversed
Definition qdir.h:56
@ LocaleAware
Definition qdir.h:59
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:2100
bool isEmpty(Filters filters=Filters(AllEntries|NoDotAndDotDot)) const
Returns whether the directory is empty.
Definition qdir.cpp:1967
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:2051
static QString rootPath()
Returns the absolute path of the root directory.
Definition qdir.cpp:2156
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:1551
QStringList nameFilters() const
Returns the string list set by setNameFilters()
Definition qdir.cpp:1050
@ Executable
Definition qdir.h:30
@ CaseSensitive
Definition qdir.h:40
@ Files
Definition qdir.h:22
@ Modified
Definition qdir.h:33
@ Hidden
Definition qdir.h:34
@ AllEntries
Definition qdir.h:25
@ Drives
Definition qdir.h:23
@ AllDirs
Definition qdir.h:39
@ NoSymLinks
Definition qdir.h:24
@ NoDotDot
Definition qdir.h:42
@ NoFilter
Definition qdir.h:45
@ Readable
Definition qdir.h:28
@ Writable
Definition qdir.h:29
@ System
Definition qdir.h:35
@ NoDotAndDotDot
Definition qdir.h:43
@ NoDot
Definition qdir.h:41
@ Dirs
Definition qdir.h:21
static QFileInfoList drives()
For Windows, returns the list of drives in the file system as a list of QFileInfo objects.
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
QDateTime lastModified() const
Returns the date and time when the file was last modified.
Definition qfileinfo.h:156
bool isSymLink() const
Returns true if this object points to a symbolic link, shortcut, or alias; otherwise returns false.
QString suffix() const
Returns the suffix (extension) of the file.
QString fileName() const
Returns the name of the file, excluding the path.
QString absoluteFilePath() const
Returns an absolute path including the file name.
bool isDir() const
Returns true if this object points to a directory or to a symbolic link to a directory.
qint64 size() const
Returns the file size in bytes.
bool isRelative() const
Returns true if the file path is relative, otherwise returns false (i.e.
bool exists() const
Returns true if the file exists; otherwise returns false.
static QFileSystemEntry canonicalName(const QFileSystemEntry &entry, QFileSystemMetaData &data)
static QAbstractFileEngine * resolveEntryAndCreateLegacyEngine(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 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:1136
bool remove()
Removes the file specified by fileName().
Definition qfile.cpp:419
Permissions permissions() const override
\reimp
Definition qfile.cpp:1107
bool rename(const QString &newName)
Renames the file currently specified by fileName() to newName.
Definition qfile.cpp:533
bool exists() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qfile.cpp:351
\inmodule QtCore
Definition qhash.h:818
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void append(parameter_type t)
Definition qlist.h:441
void clear()
Definition qlist.h:417
const_iterator ConstIterator
Definition qlist.h:251
\inmodule QtCore
Definition qmutex.h:317
\inmodule QtCore
\inmodule QtCore
static QRegularExpression fromWildcard(QStringView pattern, Qt::CaseSensitivity cs=Qt::CaseInsensitive, WildcardConversionOptions options=DefaultWildcardConversion)
\inmodule QtCore
T * data() const noexcept
Returns the value of the pointer referenced by this object.
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
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:76
constexpr void chop(qsizetype n) noexcept
Truncates this string view by length characters.
int compare(QStringView other, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
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:5299
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3794
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
static QString fromUtf16(const char16_t *, qsizetype size=-1)
Definition qstring.cpp:5883
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1101
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:898
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5350
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.cpp:6498
QString toLower() const &
Definition qstring.h:368
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
Definition qstring.cpp:5161
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4420
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:3435
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:528
T * data() noexcept
\inmodule QtCore
double e
QSet< QString >::iterator it
Combined button and popup list for selecting options.
CaseSensitivity
@ CaseInsensitive
@ CaseSensitive
@ SkipEmptyParts
Definition qnamespace.h:127
static jboolean copy(JNIEnv *, jobject)
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
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:2444
static QString qt_cleanPath(const QString &path, bool *ok=nullptr)
Definition qdir.cpp:2362
static bool treatAsAbsolute(const QString &path)
Definition qdir.cpp:754
@ OSSupportsUncPaths
Definition qdir.cpp:56
QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok)
Definition qdir.cpp:2204
QList< QFileInfo > QFileInfoList
Definition qfileinfo.h:183
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:162
return ret
GLboolean GLboolean GLboolean b
GLenum mode
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLenum type
GLsizei const GLuint * paths
GLbitfield flags
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLfloat n
const GLubyte * c
GLuint GLuint * names
GLenum GLsizei len
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static constexpr QChar sep
#define qUtf8Printable(string)
Definition qstring.h:1395
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:70
long long qint64
Definition qtypes.h:55
static int toInt(const QChar &qc, int R)
QFile file
[0]
QFileInfo info(fileName)
[8]
QFileInfo fi("c:/temp/foo")
[newstuff]
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]
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