Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qfileinfo.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 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 "qfileinfo.h"
6#include "qglobal.h"
7#include "qdir.h"
8#include "qfileinfo_p.h"
9#include "qdebug.h"
10
12
13using namespace Qt::StringLiterals;
14
16
17QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
18{
19 if (cache_enabled && !fileNames[(int)name].isNull())
20 return fileNames[(int)name];
21
22 QString ret;
23 if (fileEngine == nullptr) { // local file; use the QFileSystemEngine directly
24 switch (name) {
25 case QAbstractFileEngine::CanonicalName:
26 case QAbstractFileEngine::CanonicalPathName: {
27 QFileSystemEntry entry = QFileSystemEngine::canonicalName(fileEntry, metaData);
28 if (cache_enabled) { // be smart and store both
29 fileNames[QAbstractFileEngine::CanonicalName] = entry.filePath();
30 fileNames[QAbstractFileEngine::CanonicalPathName] = entry.path();
31 }
32 if (name == QAbstractFileEngine::CanonicalName)
33 ret = entry.filePath();
34 else
35 ret = entry.path();
36 break;
37 }
38 case QAbstractFileEngine::AbsoluteLinkTarget:
39 ret = QFileSystemEngine::getLinkTarget(fileEntry, metaData).filePath();
40 break;
41 case QAbstractFileEngine::RawLinkPath:
42 ret = QFileSystemEngine::getRawLinkPath(fileEntry, metaData).filePath();
43 break;
44 case QAbstractFileEngine::JunctionName:
45 ret = QFileSystemEngine::getJunctionTarget(fileEntry, metaData).filePath();
46 break;
47 case QAbstractFileEngine::BundleName:
48 ret = QFileSystemEngine::bundleName(fileEntry);
49 break;
50 case QAbstractFileEngine::AbsoluteName:
51 case QAbstractFileEngine::AbsolutePathName: {
52 QFileSystemEntry entry = QFileSystemEngine::absoluteName(fileEntry);
53 if (cache_enabled) { // be smart and store both
54 fileNames[QAbstractFileEngine::AbsoluteName] = entry.filePath();
55 fileNames[QAbstractFileEngine::AbsolutePathName] = entry.path();
56 }
57 if (name == QAbstractFileEngine::AbsoluteName)
58 ret = entry.filePath();
59 else
60 ret = entry.path();
61 break;
62 }
63 default: break;
64 }
65 } else {
66 ret = fileEngine->fileName(name);
67 }
68 if (ret.isNull())
69 ret = ""_L1;
70 if (cache_enabled)
71 fileNames[(int)name] = ret;
72 return ret;
73}
74
75QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const
76{
77 if (cache_enabled && !fileOwners[(int)own].isNull())
78 return fileOwners[(int)own];
79 QString ret;
80 if (fileEngine == nullptr) {
81 switch (own) {
82 case QAbstractFileEngine::OwnerUser:
83 ret = QFileSystemEngine::resolveUserName(fileEntry, metaData);
84 break;
85 case QAbstractFileEngine::OwnerGroup:
86 ret = QFileSystemEngine::resolveGroupName(fileEntry, metaData);
87 break;
88 }
89 } else {
90 ret = fileEngine->owner(own);
91 }
92 if (ret.isNull())
93 ret = ""_L1;
94 if (cache_enabled)
95 fileOwners[(int)own] = ret;
96 return ret;
97}
98
99uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) const
100{
101 Q_ASSERT(fileEngine); // should never be called when using the native FS
102 // We split the testing into tests for for LinkType, BundleType, PermsMask
103 // and the rest.
104 // Tests for file permissions on Windows can be slow, especially on network
105 // paths and NTFS drives.
106 // In order to determine if a file is a symlink or not, we have to lstat().
107 // If we're not interested in that information, we might as well avoid one
108 // extra syscall. Bundle detecton on Mac can be slow, especially on network
109 // paths, so we separate out that as well.
110
111 QAbstractFileEngine::FileFlags req;
112 uint cachedFlags = 0;
113
114 if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) {
115 if (!getCachedFlag(CachedFileFlags)) {
116 req |= QAbstractFileEngine::FlagsMask;
117 req |= QAbstractFileEngine::TypesMask;
118 req &= (~QAbstractFileEngine::LinkType);
119 req &= (~QAbstractFileEngine::BundleType);
120
121 cachedFlags |= CachedFileFlags;
122 }
123
124 if (request & QAbstractFileEngine::LinkType) {
125 if (!getCachedFlag(CachedLinkTypeFlag)) {
126 req |= QAbstractFileEngine::LinkType;
127 cachedFlags |= CachedLinkTypeFlag;
128 }
129 }
130
131 if (request & QAbstractFileEngine::BundleType) {
132 if (!getCachedFlag(CachedBundleTypeFlag)) {
133 req |= QAbstractFileEngine::BundleType;
134 cachedFlags |= CachedBundleTypeFlag;
135 }
136 }
137 }
138
139 if (request & QAbstractFileEngine::PermsMask) {
140 if (!getCachedFlag(CachedPerms)) {
141 req |= QAbstractFileEngine::PermsMask;
142 cachedFlags |= CachedPerms;
143 }
144 }
145
146 if (req) {
147 if (cache_enabled)
148 req &= (~QAbstractFileEngine::Refresh);
149 else
150 req |= QAbstractFileEngine::Refresh;
151
152 QAbstractFileEngine::FileFlags flags = fileEngine->fileFlags(req);
153 fileFlags |= uint(flags.toInt());
154 setCachedFlag(cachedFlags);
155 }
156
157 return fileFlags & request.toInt();
158}
159
160QDateTime &QFileInfoPrivate::getFileTime(QFile::FileTime request) const
161{
162 Q_ASSERT(fileEngine); // should never be called when using the native FS
163 if (!cache_enabled)
165
166 uint cf = 0;
167 switch (request) {
168 case QFile::FileAccessTime:
169 cf = CachedATime;
170 break;
171 case QFile::FileBirthTime:
172 cf = CachedBTime;
173 break;
174 case QFile::FileMetadataChangeTime:
175 cf = CachedMCTime;
176 break;
177 case QFile::FileModificationTime:
178 cf = CachedMTime;
179 break;
180 }
181
182 if (!getCachedFlag(cf)) {
183 fileTimes[request] = fileEngine->fileTime(request);
184 setCachedFlag(cf);
185 }
186 return fileTimes[request];
187}
188
189//************* QFileInfo
190
191/*!
192 \class QFileInfo
193 \inmodule QtCore
194 \reentrant
195 \brief The QFileInfo class provides an OS-independent API to retrieve
196 information about file system entries.
197
198 \ingroup io
199 \ingroup shared
200
201 \compares equality
202
203 QFileInfo provides information about a file system entry, such as its
204 name, path, access rights and whether it is a regular file, directory or
205 symbolic link. The entry's size and last modified/read times are also
206 available. QFileInfo can also be used to obtain information about a Qt
207 \l{resource system}{resource}.
208
209 A QFileInfo can point to a file system entry with either an absolute or
210 a relative path:
211 \list
212 \li \include qfileinfo.cpp absolute-path-unix-windows
213
214 \li \include qfileinfo.cpp relative-path-note
215 \endlist
216
217 An example of an absolute path is the string \c {"/tmp/quartz"}. A relative
218 path may look like \c {"src/fatlib"}. You can use the function isRelative()
219 to check whether a QFileInfo is using a relative or an absolute path. You
220 can call the function makeAbsolute() to convert a relative QFileInfo's
221 path to an absolute path.
222
223//! [qresource-virtual-fs-colon]
224 \note Paths starting with a colon (\e{:}) are always considered
225 absolute, as they denote a QResource.
226//! [qresource-virtual-fs-colon]
227
228 The file system entry path that the QFileInfo works on is set in the
229 constructor or later with setFile(). Use exists() to see if the entry
230 actually exists and size() to get its size.
231
232 The file system entry's type is obtained with isFile(), isDir(), and
233 isSymLink(). The symLinkTarget() function provides the absolute path of
234 the target the symlink points to.
235
236 The path elements of the file system entry can be extracted with path()
237 and fileName(). The fileName()'s parts can be extracted with baseName(),
238 suffix(), or completeSuffix(). QFileInfo objects referring to directories
239 created by Qt classes will not have a trailing directory separator
240 \c{'/'}. If you wish to use trailing separators in your own file info
241 objects, just append one to the entry's path given to the constructors
242 or setFile().
243
244 Date and time related information are returned by birthTime(), fileTime(),
245 lastModified(), lastRead(), and metadataChangeTime().
246 Information about
247 access permissions can be obtained with isReadable(), isWritable(), and
248 isExecutable(). Ownership information can be obtained with
249 owner(), ownerId(), group(), and groupId(). You can also examine
250 permissions and ownership in a single statement using the permission()
251 function.
252
253 \section1 Symbolic Links and Shortcuts
254
255 On Unix (including \macos and iOS), the property getter functions in
256 this class return the properties such as times and size of the target,
257 not the symlink, because Unix handles symlinks transparently. Opening
258 a symlink using QFile effectively opens the link's target. For example:
259
260 \snippet code/src_corelib_io_qfileinfo.cpp 0
261
262 On Windows, shortcuts (\c .lnk files) are currently treated as symlinks. As
263 on Unix systems, the property getters return the size of the target,
264 not the \c .lnk file itself. This behavior is deprecated and will likely
265 be removed in a future version of Qt, after which \c .lnk files will be
266 treated as regular files.
267
268 \snippet code/src_corelib_io_qfileinfo.cpp 1
269
270 \section1 NTFS permissions
271
272 On NTFS file systems, ownership and permissions checking is
273 disabled by default for performance reasons. To enable it,
274 include the following line:
275
276 \snippet ntfsp.cpp 0
277
278 Permission checking is then turned on and off by incrementing and
279 decrementing \c qt_ntfs_permission_lookup by 1.
280
281 \snippet ntfsp.cpp 1
282
283 \note Since this is a non-atomic global variable, it is only safe
284 to increment or decrement \c qt_ntfs_permission_lookup before any
285 threads other than the main thread have started or after every thread
286 other than the main thread has ended.
287
288 \note From Qt 6.6 the variable \c qt_ntfs_permission_lookup is
289 deprecated. Please use the following alternatives.
290
291 The safe and easy way to manage permission checks is to use the RAII class
292 \c QNtfsPermissionCheckGuard.
293
294 \snippet ntfsp.cpp raii
295
296 If you need more fine-grained control, it is possible to manage the permission
297 with the following functions instead:
298
299 \snippet ntfsp.cpp free-funcs
300
301 \section1 Performance Considerations
302
303 Some of QFileInfo's functions have to query the file system, but for
304 performance reasons, some functions only operate on the path string.
305 For example: To return the absolute path of a relative entry's path,
306 absolutePath() has to query the file system. The path() function, however,
307 can work on the file name directly, and so it is faster.
308
309 QFileInfo also caches information about the file system entry it refers
310 to. Because the file system can be changed by other users or programs,
311 or even by other parts of the same program, there is a function that
312 refreshes the information stored in QFileInfo, namely refresh(). To switch
313 off a QFileInfo's caching (that is, force it to query the underlying file
314 system every time you request information from it), call setCaching(false).
315
316 Fetching information from the file system is typically done by calling
317 (possibly) expensive system functions, so QFileInfo (depending on the
318 implementation) might not fetch all the information from the file system
319 at construction. To make sure that all information is read from the file
320 system immediately, use the stat() member function.
321
322 \l{birthTime()}, \l{fileTime()}, \l{lastModified()}, \l{lastRead()},
323 and \l{metadataChangeTime()} return times in \e{local time} by default.
324 Since native file system API typically uses UTC, this requires a conversion.
325 If you don't actually need the local time, you can avoid this by requesting
326 the time in QTimeZone::UTC directly.
327
328 \section1 Platform Specific Issues
329
330 \include android-content-uri-limitations.qdocinc
331
332 \sa QDir, QFile
333*/
334
335/*!
336 \fn QFileInfo &QFileInfo::operator=(QFileInfo &&other)
337
338 Move-assigns \a other to this QFileInfo instance.
339
340 \since 5.2
341*/
342
343/*!
344 \internal
345*/
346QFileInfo::QFileInfo(QFileInfoPrivate *p) : d_ptr(p)
347{
348}
349
350/*!
351 Constructs an empty QFileInfo object that doesn't refer to any file
352 system entry.
353
354 \sa setFile()
355*/
356QFileInfo::QFileInfo() : d_ptr(new QFileInfoPrivate())
357{
358}
359
360/*!
361 Constructs a QFileInfo that gives information about a file system entry
362 located at \a path that can be absolute or relative.
363
364//! [preserve-relative-path]
365 If \a path is relative, the QFileInfo will also have a relative path.
366//! [preserve-relative-path]
367
368 \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
369*/
370QFileInfo::QFileInfo(const QString &path) : d_ptr(new QFileInfoPrivate(path))
371{
372}
373
374/*!
375 Constructs a new QFileInfo that gives information about file \a
376 file.
377
378 If the \a file has a relative path, the QFileInfo will also have a
379 relative path.
380
381 \sa isRelative()
382*/
383QFileInfo::QFileInfo(const QFileDevice &file) : d_ptr(new QFileInfoPrivate(file.fileName()))
384{
385}
386
387/*!
388 Constructs a new QFileInfo that gives information about the given
389 file system entry \a path that is relative to the directory \a dir.
390
391//! [preserve-relative-or-absolute]
392 If \a dir has a relative path, the QFileInfo will also have a
393 relative path.
394
395 If \a path is absolute, then the directory specified by \a dir
396 will be disregarded.
397//! [preserve-relative-or-absolute]
398
399 \sa isRelative()
400*/
401QFileInfo::QFileInfo(const QDir &dir, const QString &path)
402 : d_ptr(new QFileInfoPrivate(dir.filePath(path)))
403{
404}
405
406/*!
407 Constructs a new QFileInfo that is a copy of the given \a fileinfo.
408*/
409QFileInfo::QFileInfo(const QFileInfo &fileinfo)
410 : d_ptr(fileinfo.d_ptr)
411{
412
413}
414
415/*!
416 Destroys the QFileInfo and frees its resources.
417*/
418
419QFileInfo::~QFileInfo()
420{
421}
422
423/*!
424 \fn bool QFileInfo::operator!=(const QFileInfo &lhs, const QFileInfo &rhs)
425
426 Returns \c true if QFileInfo \a lhs refers to a different file system
427 entry than the one referred to by \a rhs; otherwise returns \c false.
428
429 \sa operator==()
430*/
431
432/*!
433 \fn bool QFileInfo::operator==(const QFileInfo &lhs, const QFileInfo &rhs)
434
435 Returns \c true if QFileInfo \a lhs and QFileInfo \a rhs refer to the same
436 entry on the file system; otherwise returns \c false.
437
438 Note that the result of comparing two empty QFileInfo objects, containing
439 no file system entry references (paths that do not exist or are empty),
440 is undefined.
441
442 \warning This will not compare two different symbolic links pointing to
443 the same target.
444
445 \warning On Windows, long and short paths that refer to the same file
446 system entry are treated as if they referred to different entries.
447
448 \sa operator!=()
449*/
450bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)
451{
452 if (rhs.d_ptr == lhs.d_ptr)
453 return true;
454 if (lhs.d_ptr->isDefaultConstructed || rhs.d_ptr->isDefaultConstructed)
455 return false;
456
457 // Assume files are the same if path is the same
458 if (lhs.d_ptr->fileEntry.filePath() == rhs.d_ptr->fileEntry.filePath())
459 return true;
460
461 Qt::CaseSensitivity sensitive;
462 if (lhs.d_ptr->fileEngine == nullptr || rhs.d_ptr->fileEngine == nullptr) {
463 if (lhs.d_ptr->fileEngine != rhs.d_ptr->fileEngine) // one is native, the other is a custom file-engine
464 return false;
465
466 const bool lhsCaseSensitive = QFileSystemEngine::isCaseSensitive(lhs.d_ptr->fileEntry, lhs.d_ptr->metaData);
467 if (lhsCaseSensitive != QFileSystemEngine::isCaseSensitive(rhs.d_ptr->fileEntry, rhs.d_ptr->metaData))
468 return false;
469
470 sensitive = lhsCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
471 } else {
472 if (lhs.d_ptr->fileEngine->caseSensitive() != rhs.d_ptr->fileEngine->caseSensitive())
473 return false;
474 sensitive = lhs.d_ptr->fileEngine->caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
475 }
476
477 // Fallback to expensive canonical path computation
478 return lhs.canonicalFilePath().compare(rhs.canonicalFilePath(), sensitive) == 0;
479}
480
481/*!
482 Makes a copy of the given \a fileinfo and assigns it to this QFileInfo.
483*/
484QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo)
485{
486 d_ptr = fileinfo.d_ptr;
487 return *this;
488}
489
490/*!
491 \fn void QFileInfo::swap(QFileInfo &other)
492 \since 5.0
493 \memberswap{file info}
494*/
495
496/*!
497 Sets the path of the file system entry that this QFileInfo provides
498 information about to \a path that can be absolute or relative.
499
500//! [absolute-path-unix-windows]
501 On Unix, absolute paths begin with the directory separator \c {'/'}.
502 On Windows, absolute paths begin with a drive specification (for example,
503 \c {D:/}).
504//! [ absolute-path-unix-windows]
505
506//! [relative-path-note]
507 Relative paths begin with a directory name or a regular file name and
508 specify a file system entry's path relative to the current working
509 directory.
510//! [relative-path-note]
511
512 Example:
513 \snippet code/src_corelib_io_qfileinfo.cpp 2
514
515 \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
516*/
517void QFileInfo::setFile(const QString &path)
518{
519 bool caching = d_ptr.constData()->cache_enabled;
520 *this = QFileInfo(path);
521 d_ptr->cache_enabled = caching;
522}
523
524/*!
525 \overload
526
527 Sets the file that the QFileInfo provides information about to \a
528 file.
529
530 If \a file includes a relative path, the QFileInfo will also have
531 a relative path.
532
533 \sa isRelative()
534*/
535void QFileInfo::setFile(const QFileDevice &file)
536{
537 setFile(file.fileName());
538}
539
540/*!
541 \overload
542
543 Sets the path of the file system entry that this QFileInfo provides
544 information about to \a path in directory \a dir.
545
546 \include qfileinfo.cpp preserve-relative-or-absolute
547
548 \sa isRelative()
549*/
550void QFileInfo::setFile(const QDir &dir, const QString &path)
551{
552 setFile(dir.filePath(path));
553}
554
555/*!
556 Returns the absolute full path to the file system entry this QFileInfo
557 refers to, including the entry's name.
558
559 \include qfileinfo.cpp absolute-path-unix-windows
560
561//! [windows-network-shares]
562 On Windows, the paths of network shares that are not mapped to a drive
563 letter begin with \c{//sharename/}.
564//! [windows-network-shares]
565
566 QFileInfo will uppercase drive letters. Note that QDir does not do
567 this. The code snippet below shows this.
568
569 \snippet code/src_corelib_io_qfileinfo.cpp newstuff
570
571 This function returns the same as filePath(), unless isRelative()
572 is true. In contrast to canonicalFilePath(), symbolic links or
573 redundant "." or ".." elements are not necessarily removed.
574
575 \warning If filePath() is empty the behavior of this function
576 is undefined.
577
578 \sa filePath(), canonicalFilePath(), isRelative()
579*/
580QString QFileInfo::absoluteFilePath() const
581{
582 Q_D(const QFileInfo);
583 if (d->isDefaultConstructed)
584 return ""_L1;
585 return d->getFileName(QAbstractFileEngine::AbsoluteName);
586}
587
588/*!
589 Returns the file system entry's canonical path, including the entry's
590 name, that is, an absolute path without symbolic links or redundant
591 \c{'.'} or \c{'..'} elements.
592
593 If the entry does not exist, canonicalFilePath() returns an empty
594 string.
595
596 \sa filePath(), absoluteFilePath(), dir()
597*/
598QString QFileInfo::canonicalFilePath() const
599{
600 Q_D(const QFileInfo);
601 if (d->isDefaultConstructed)
602 return ""_L1;
603 return d->getFileName(QAbstractFileEngine::CanonicalName);
604}
605
606
607/*!
608 Returns the absolute path of the file system entry this QFileInfo refers to,
609 excluding the entry's name.
610
611 \include qfileinfo.cpp absolute-path-unix-windows
612
613 \include qfileinfo.cpp windows-network-shares
614
615 In contrast to canonicalPath() symbolic links or redundant "." or
616 ".." elements are not necessarily removed.
617
618 \warning If filePath() is empty the behavior of this function
619 is undefined.
620
621 \sa absoluteFilePath(), path(), canonicalPath(), fileName(), isRelative()
622*/
623QString QFileInfo::absolutePath() const
624{
625 Q_D(const QFileInfo);
626
627 if (d->isDefaultConstructed)
628 return ""_L1;
629 return d->getFileName(QAbstractFileEngine::AbsolutePathName);
630}
631
632/*!
633 Returns the file system entry's canonical path (excluding the entry's name),
634 i.e. an absolute path without symbolic links or redundant "." or ".." elements.
635
636 If the entry does not exist, this method returns an empty string.
637
638 \sa path(), absolutePath()
639*/
640QString QFileInfo::canonicalPath() const
641{
642 Q_D(const QFileInfo);
643 if (d->isDefaultConstructed)
644 return ""_L1;
645 return d->getFileName(QAbstractFileEngine::CanonicalPathName);
646}
647
648/*!
649 Returns the path of the file system entry this QFileInfo refers to,
650 excluding the entry's name.
651
652 \include qfileinfo.cpp path-ends-with-slash-empty-name-component
653 In this case, this function will return the entire path.
654
655 \sa filePath(), absolutePath(), canonicalPath(), dir(), fileName(), isRelative()
656*/
657QString QFileInfo::path() const
658{
659 Q_D(const QFileInfo);
660 if (d->isDefaultConstructed)
661 return ""_L1;
662 return d->fileEntry.path();
663}
664
665/*!
666 \fn bool QFileInfo::isAbsolute() const
667
668 Returns \c true if the file system entry's path is absolute, otherwise
669 returns \c false (that is, the path is relative).
670
671 \include qfileinfo.cpp qresource-virtual-fs-colon
672
673 \sa isRelative()
674*/
675
676/*!
677 Returns \c true if the file system entry's path is relative, otherwise
678 returns \c false (that is, the path is absolute).
679
680 \include qfileinfo.cpp absolute-path-unix-windows
681
682 \include qfileinfo.cpp qresource-virtual-fs-colon
683
684 \sa isAbsolute()
685*/
686bool QFileInfo::isRelative() const
687{
688 Q_D(const QFileInfo);
689 if (d->isDefaultConstructed)
690 return true;
691 if (d->fileEngine == nullptr)
692 return d->fileEntry.isRelative();
693 return d->fileEngine->isRelativePath();
694}
695
696/*!
697 If the file system entry's path is relative, this method converts it to
698 an absolute path and returns \c true; if the path is already absolute,
699 this method returns \c false.
700
701 \sa filePath(), isRelative()
702*/
703bool QFileInfo::makeAbsolute()
704{
705 if (d_ptr.constData()->isDefaultConstructed
706 || !d_ptr.constData()->fileEntry.isRelative())
707 return false;
708
709 setFile(absoluteFilePath());
710 return true;
711}
712
713/*!
714 Returns \c true if the file system entry this QFileInfo refers to exists;
715 otherwise returns \c false.
716
717 \note If the entry is a symlink that points to a non-existing
718 target, this method returns \c false.
719*/
720bool QFileInfo::exists() const
721{
722 Q_D(const QFileInfo);
723 if (d->isDefaultConstructed)
724 return false;
725 if (d->fileEngine == nullptr) {
726 if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute))
727 QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute);
728 return d->metaData.exists();
729 }
730 return d->getFileFlags(QAbstractFileEngine::ExistsFlag);
731}
732
733/*!
734 \since 5.2
735
736 Returns \c true if the file system entry \a path exists; otherwise
737 returns \c false.
738
739 \note If \a path is a symlink that points to a non-existing
740 target, this method returns \c false.
741
742 \note Using this function is faster than using
743 \c QFileInfo(path).exists() for file system access.
744*/
745bool QFileInfo::exists(const QString &path)
746{
747 if (path.isEmpty())
748 return false;
749 QFileSystemEntry entry(path);
750 QFileSystemMetaData data;
751 // Expensive fallback to non-QFileSystemEngine implementation
752 if (auto engine = QFileSystemEngine::createLegacyEngine(entry, data))
753 return QFileInfo(new QFileInfoPrivate(entry, data, std::move(engine))).exists();
754
755 QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
756 return data.exists();
757}
758
759/*!
760 Refreshes the information about the file system entry this QFileInfo
761 refers to, that is, reads in information from the file system the next
762 time a cached property is fetched.
763*/
764void QFileInfo::refresh()
765{
766 Q_D(QFileInfo);
767 d->clear();
768}
769
770/*!
771 Returns the path of the file system entry this QFileInfo refers to;
772 the path may be absolute or relative.
773
774 \sa absoluteFilePath(), canonicalFilePath(), isRelative()
775*/
776QString QFileInfo::filePath() const
777{
778 Q_D(const QFileInfo);
779 if (d->isDefaultConstructed)
780 return ""_L1;
781 return d->fileEntry.filePath();
782}
783
784/*!
785 Returns the name of the file system entry this QFileInfo refers to,
786 excluding the path.
787
788 Example:
789 \snippet code/src_corelib_io_qfileinfo.cpp 3
790
791//! [path-ends-with-slash-empty-name-component]
792 \note If this QFileInfo is given a path ending with a directory separator
793 \c{'/'}, the entry's name part is considered empty.
794//! [path-ends-with-slash-empty-name-component]
795
796 \sa isRelative(), filePath(), baseName(), suffix()
797*/
798QString QFileInfo::fileName() const
799{
800 Q_D(const QFileInfo);
801 if (d->isDefaultConstructed)
802 return ""_L1;
803 if (!d->fileEngine)
804 return d->fileEntry.fileName();
805 return d->fileEngine->fileName(QAbstractFileEngine::BaseName);
806}
807
808/*!
809 \since 4.3
810 Returns the name of the bundle.
811
812 On \macos and iOS this returns the proper localized name for a bundle if the
813 path isBundle(). On all other platforms an empty QString is returned.
814
815 Example:
816 \snippet code/src_corelib_io_qfileinfo.cpp 4
817
818 \sa isBundle(), filePath(), baseName(), suffix()
819*/
820QString QFileInfo::bundleName() const
821{
822 Q_D(const QFileInfo);
823 if (d->isDefaultConstructed)
824 return ""_L1;
825 return d->getFileName(QAbstractFileEngine::BundleName);
826}
827
828/*!
829 Returns the base name of the file without the path.
830
831 The base name consists of all characters in the file up to (but
832 not including) the \e first '.' character.
833
834 Example:
835 \snippet code/src_corelib_io_qfileinfo.cpp 5
836
837
838 The base name of a file is computed equally on all platforms, independent
839 of file naming conventions (e.g., ".bashrc" on Unix has an empty base
840 name, and the suffix is "bashrc").
841
842 \sa fileName(), suffix(), completeSuffix(), completeBaseName()
843*/
844QString QFileInfo::baseName() const
845{
846 Q_D(const QFileInfo);
847 if (d->isDefaultConstructed)
848 return ""_L1;
849 if (!d->fileEngine)
850 return d->fileEntry.baseName();
851 return QFileSystemEntry(d->fileEngine->fileName(QAbstractFileEngine::BaseName)).baseName();
852}
853
854/*!
855 Returns the complete base name of the file without the path.
856
857 The complete base name consists of all characters in the file up
858 to (but not including) the \e last '.' character.
859
860 Example:
861 \snippet code/src_corelib_io_qfileinfo.cpp 6
862
863 \sa fileName(), suffix(), completeSuffix(), baseName()
864*/
865QString QFileInfo::completeBaseName() const
866{
867 Q_D(const QFileInfo);
868 if (d->isDefaultConstructed)
869 return ""_L1;
870 if (!d->fileEngine)
871 return d->fileEntry.completeBaseName();
872 const QString fileEngineBaseName = d->fileEngine->fileName(QAbstractFileEngine::BaseName);
873 return QFileSystemEntry(fileEngineBaseName).completeBaseName();
874}
875
876/*!
877 Returns the complete suffix (extension) of the file.
878
879 The complete suffix consists of all characters in the file after
880 (but not including) the first '.'.
881
882 Example:
883 \snippet code/src_corelib_io_qfileinfo.cpp 7
884
885 \sa fileName(), suffix(), baseName(), completeBaseName()
886*/
887QString QFileInfo::completeSuffix() const
888{
889 Q_D(const QFileInfo);
890 if (d->isDefaultConstructed)
891 return ""_L1;
892 return d->fileEntry.completeSuffix();
893}
894
895/*!
896 Returns the suffix (extension) of the file.
897
898 The suffix consists of all characters in the file after (but not
899 including) the last '.'.
900
901 Example:
902 \snippet code/src_corelib_io_qfileinfo.cpp 8
903
904 The suffix of a file is computed equally on all platforms, independent of
905 file naming conventions (e.g., ".bashrc" on Unix has an empty base name,
906 and the suffix is "bashrc").
907
908 \sa fileName(), completeSuffix(), baseName(), completeBaseName()
909*/
910QString QFileInfo::suffix() const
911{
912 Q_D(const QFileInfo);
913 if (d->isDefaultConstructed)
914 return ""_L1;
915 return d->fileEntry.suffix();
916}
917
918
919/*!
920 Returns a QDir object representing the path of the parent directory of the
921 file system entry that this QFileInfo refers to.
922
923 \note The QDir returned always corresponds to the object's
924 parent directory, even if the QFileInfo represents a directory.
925
926 For each of the following, dir() returns the QDir
927 \c{"~/examples/191697"}.
928
929 \snippet fileinfo/main.cpp 0
930
931 For each of the following, dir() returns the QDir
932 \c{"."}.
933
934 \snippet fileinfo/main.cpp 1
935
936 \sa absolutePath(), filePath(), fileName(), isRelative(), absoluteDir()
937*/
938QDir QFileInfo::dir() const
939{
940 Q_D(const QFileInfo);
941 return QDir(d->fileEntry.path());
942}
943
944/*!
945 Returns a QDir object representing the absolute path of the parent
946 directory of the file system entry that this QFileInfo refers to.
947
948 \snippet code/src_corelib_io_qfileinfo.cpp 11
949
950 \sa dir(), filePath(), fileName(), isRelative()
951*/
952QDir QFileInfo::absoluteDir() const
953{
954 return QDir(absolutePath());
955}
956
957/*!
958 Returns \c true if the user can read the file system entry this QFileInfo
959 refers to; otherwise returns \c false.
960
961 \include qfileinfo.cpp info-about-target-not-symlink
962
963 \note If the \l{NTFS permissions} check has not been enabled, the result
964 on Windows will merely reflect whether the entry exists.
965
966 \sa isWritable(), isExecutable(), permission()
967*/
968bool QFileInfo::isReadable() const
969{
970 Q_D(const QFileInfo);
971 return d->checkAttribute<bool>(
972 QFileSystemMetaData::UserReadPermission,
973 [d]() { return d->metaData.isReadable(); },
974 [d]() { return d->getFileFlags(QAbstractFileEngine::ReadUserPerm); });
975}
976
977/*!
978 Returns \c true if the user can write to the file system entry this
979 QFileInfo refers to; otherwise returns \c false.
980
981 \include qfileinfo.cpp info-about-target-not-symlink
982
983 \note If the \l{NTFS permissions} check has not been enabled, the result on
984 Windows will merely reflect whether the entry is marked as Read Only.
985
986 \sa isReadable(), isExecutable(), permission()
987*/
988bool QFileInfo::isWritable() const
989{
990 Q_D(const QFileInfo);
991 return d->checkAttribute<bool>(
992 QFileSystemMetaData::UserWritePermission,
993 [d]() { return d->metaData.isWritable(); },
994 [d]() { return d->getFileFlags(QAbstractFileEngine::WriteUserPerm); });
995}
996
997/*!
998 Returns \c true if the file system entry this QFileInfo refers to is
999 executable; otherwise returns \c false.
1000
1001//! [info-about-target-not-symlink]
1002 If the file is a symlink, this function returns information about the
1003 target, not the symlink.
1004//! [info-about-target-not-symlink]
1005
1006 \sa isReadable(), isWritable(), permission()
1007*/
1008bool QFileInfo::isExecutable() const
1009{
1010 Q_D(const QFileInfo);
1011 return d->checkAttribute<bool>(
1012 QFileSystemMetaData::UserExecutePermission,
1013 [d]() { return d->metaData.isExecutable(); },
1014 [d]() { return d->getFileFlags(QAbstractFileEngine::ExeUserPerm); });
1015}
1016
1017/*!
1018 Returns \c true if the file system entry this QFileInfo refers to is
1019 `hidden'; otherwise returns \c false.
1020
1021 \b{Note:} This function returns \c true for the special entries "." and
1022 ".." on Unix, even though QDir::entryList treats them as shown. And note
1023 that, since this function inspects the file name, on Unix it will inspect
1024 the name of the symlink, if this file is a symlink, not the target's name.
1025
1026 On Windows, this function returns \c true if the target file is hidden (not
1027 the symlink).
1028*/
1029bool QFileInfo::isHidden() const
1030{
1031 Q_D(const QFileInfo);
1032 return d->checkAttribute<bool>(
1033 QFileSystemMetaData::HiddenAttribute,
1034 [d]() { return d->metaData.isHidden(); },
1035 [d]() { return d->getFileFlags(QAbstractFileEngine::HiddenFlag); });
1036}
1037
1038/*!
1039 \since 5.0
1040 Returns \c true if the file path can be used directly with native APIs.
1041 Returns \c false if the file is otherwise supported by a virtual file system
1042 inside Qt, such as \l{the Qt Resource System}.
1043
1044 \b{Note:} Native paths may still require conversion of path separators
1045 and character encoding, depending on platform and input requirements of the
1046 native API.
1047
1048 \sa QDir::toNativeSeparators(), QFile::encodeName(), filePath(),
1049 absoluteFilePath(), canonicalFilePath()
1050*/
1051bool QFileInfo::isNativePath() const
1052{
1053 Q_D(const QFileInfo);
1054 if (d->isDefaultConstructed)
1055 return false;
1056 if (d->fileEngine == nullptr)
1057 return true;
1058 return d->getFileFlags(QAbstractFileEngine::LocalDiskFlag);
1059}
1060
1061/*!
1062 Returns \c true if this object points to a file or to a symbolic
1063 link to a file. Returns \c false if the
1064 object points to something that is not a file (such as a directory)
1065 or that does not exist.
1066
1067 \include qfileinfo.cpp info-about-target-not-symlink
1068
1069 \sa isDir(), isSymLink(), isBundle()
1070*/
1071bool QFileInfo::isFile() const
1072{
1073 Q_D(const QFileInfo);
1074 return d->checkAttribute<bool>(
1075 QFileSystemMetaData::FileType,
1076 [d]() { return d->metaData.isFile(); },
1077 [d]() { return d->getFileFlags(QAbstractFileEngine::FileType); });
1078}
1079
1080/*!
1081 Returns \c true if this object points to a directory or to a symbolic
1082 link to a directory. Returns \c false if the
1083 object points to something that is not a directory (such as a file)
1084 or that does not exist.
1085
1086 \include qfileinfo.cpp info-about-target-not-symlink
1087
1088 \sa isFile(), isSymLink(), isBundle()
1089*/
1090bool QFileInfo::isDir() const
1091{
1092 Q_D(const QFileInfo);
1093 return d->checkAttribute<bool>(
1094 QFileSystemMetaData::DirectoryType,
1095 [d]() { return d->metaData.isDirectory(); },
1096 [d]() { return d->getFileFlags(QAbstractFileEngine::DirectoryType); });
1097}
1098
1099
1100/*!
1101 \since 4.3
1102 Returns \c true if this object points to a bundle or to a symbolic
1103 link to a bundle on \macos and iOS; otherwise returns \c false.
1104
1105 \include qfileinfo.cpp info-about-target-not-symlink
1106
1107 \sa isDir(), isSymLink(), isFile()
1108*/
1109bool QFileInfo::isBundle() const
1110{
1111 Q_D(const QFileInfo);
1112 return d->checkAttribute<bool>(
1113 QFileSystemMetaData::BundleType,
1114 [d]() { return d->metaData.isBundle(); },
1115 [d]() { return d->getFileFlags(QAbstractFileEngine::BundleType); });
1116}
1117
1118/*!
1119 Returns \c true if this object points to a symbolic link, shortcut,
1120 or alias; otherwise returns \c false.
1121
1122 Symbolic links exist on Unix (including \macos and iOS) and Windows
1123 and are typically created by the \c{ln -s} or \c{mklink} commands,
1124 respectively. Opening a symbolic link effectively opens
1125 the \l{symLinkTarget()}{link's target}.
1126
1127 In addition, true will be returned for shortcuts (\c *.lnk files) on
1128 Windows, and aliases on \macos. This behavior is deprecated and will
1129 likely change in a future version of Qt. Opening a shortcut or alias
1130 will open the \c .lnk or alias file itself.
1131
1132 Example:
1133
1134 \snippet code/src_corelib_io_qfileinfo.cpp 9
1135
1136//! [symlink-target-exists-behavior]
1137 \note exists() returns \c true if the symlink points to an existing
1138 target, otherwise it returns \c false.
1139//! [symlink-target-exists-behavior]
1140
1141 \sa isFile(), isDir(), symLinkTarget()
1142*/
1143bool QFileInfo::isSymLink() const
1144{
1145 Q_D(const QFileInfo);
1146 return d->checkAttribute<bool>(
1147 QFileSystemMetaData::LegacyLinkType,
1148 [d]() { return d->metaData.isLegacyLink(); },
1149 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1150}
1151
1152/*!
1153 Returns \c true if this object points to a symbolic link;
1154 otherwise returns \c false.
1155
1156 Symbolic links exist on Unix (including \macos and iOS) and Windows
1157 (NTFS-symlink) and are typically created by the \c{ln -s} or \c{mklink}
1158 commands, respectively.
1159
1160 Unix handles symlinks transparently. Opening a symbolic link effectively
1161 opens the \l{symLinkTarget()}{link's target}.
1162
1163 In contrast to isSymLink(), false will be returned for shortcuts
1164 (\c *.lnk files) on Windows and aliases on \macos. Use QFileInfo::isShortcut()
1165 and QFileInfo::isAlias() instead.
1166
1167 \include qfileinfo.cpp symlink-target-exists-behavior
1168
1169 \sa isFile(), isDir(), isShortcut(), symLinkTarget()
1170*/
1171
1172bool QFileInfo::isSymbolicLink() const
1173{
1174 Q_D(const QFileInfo);
1175 return d->checkAttribute<bool>(
1176 QFileSystemMetaData::LegacyLinkType,
1177 [d]() { return d->metaData.isLink(); },
1178 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1179}
1180
1181/*!
1182 \since 6.10
1183
1184 Returns \c true if this QFileInfo refers to a file system entry that is
1185 \e not a directory, regular file or symbolic link. Otherwise returns
1186 \c false.
1187
1188 If this QFileInfo refers to a nonexistent entry, this method returns
1189 \c false.
1190
1191 If the entry is a dangling symbolic link (the target doesn't exist), this
1192 method returns \c false. For a non-dangling symbolic link, this function
1193 returns information about the target, not the symbolic link.
1194
1195 On Unix a special (other) file system entry is a FIFO, socket, character
1196 device, or block device. For more details, see the
1197 \l{https://pubs.opengroup.org/onlinepubs/9699919799/functions/mknod.html}{\c mknod}
1198 manual page.
1199
1200 On Windows (for historical reasons, see \l{Symbolic Links and Shortcuts})
1201 this method returns \c true for \c .lnk files.
1202
1203 \sa isDir(), isFile(), isSymLink(), QDirListing::IteratorFlag::ExcludeOther
1204*/
1205bool QFileInfo::isOther() const
1206{
1207 Q_D(const QFileInfo);
1208 using M = QFileSystemMetaData::MetaDataFlag;
1209 // No M::LinkType to make QFileSystemEngine always call stat().
1210 // M::WinLnkType is only relevant on Windows for '.lnk' files
1211 constexpr auto mdFlags = M::ExistsAttribute | M::DirectoryType | M::FileType | M::WinLnkType;
1212
1213 auto fsLambda = [d]() {
1214 // Check isLnkFile() first because currently exists() returns false for
1215 // a broken '.lnk' where the target doesn't exist.
1216 if (d->metaData.isLnkFile()) // Always false on non-Windows OSes
1217 return true;
1218 return d->metaData.exists() && !d->metaData.isDirectory() && !d->metaData.isFile();
1219 };
1220
1221 auto engineLambda = [d]() {
1222 using F = QAbstractFileEngine::FileFlag;
1223 return d->getFileFlags(F::ExistsFlag)
1224 && !d->getFileFlags(F::LinkType) // QAFE doesn't have a separate type for ".lnk" file
1225 && !d->getFileFlags(F::DirectoryType)
1226 && !d->getFileFlags(F::FileType);
1227 };
1228
1229 return d->checkAttribute<bool>(mdFlags, std::move(fsLambda), std::move(engineLambda));
1230}
1231
1232/*!
1233 Returns \c true if this object points to a shortcut;
1234 otherwise returns \c false.
1235
1236 Shortcuts only exist on Windows and are typically \c .lnk files.
1237 For instance, true will be returned for shortcuts (\c *.lnk files) on
1238 Windows, but false will be returned on Unix (including \macos and iOS).
1239
1240 The shortcut (.lnk) files are treated as regular files. Opening those will
1241 open the \c .lnk file itself. In order to open the file a shortcut
1242 references to, it must uses symLinkTarget() on a shortcut.
1243
1244 \note Even if a shortcut (broken shortcut) points to a non existing file,
1245 isShortcut() returns true.
1246
1247 \sa isFile(), isDir(), isSymbolicLink(), symLinkTarget()
1248*/
1249bool QFileInfo::isShortcut() const
1250{
1251 Q_D(const QFileInfo);
1252 return d->checkAttribute<bool>(
1253 QFileSystemMetaData::LegacyLinkType,
1254 [d]() { return d->metaData.isLnkFile(); },
1255 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1256}
1257
1258/*!
1259 Returns \c true if this object points to an alias;
1260 otherwise returns \c false.
1261
1262 \since 6.4
1263
1264 Aliases only exist on \macos. They are treated as regular files, so
1265 opening an alias will open the file itself. In order to open the file
1266 or directory an alias references use symLinkTarget().
1267
1268 \note Even if an alias points to a non existing file,
1269 isAlias() returns true.
1270
1271 \sa isFile(), isDir(), isSymLink(), symLinkTarget()
1272*/
1273bool QFileInfo::isAlias() const
1274{
1275 Q_D(const QFileInfo);
1276 return d->checkAttribute<bool>(
1277 QFileSystemMetaData::LegacyLinkType,
1278 [d]() { return d->metaData.isAlias(); },
1279 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1280}
1281
1282/*!
1283 \since 5.15
1284
1285 Returns \c true if the object points to a junction;
1286 otherwise returns \c false.
1287
1288 Junctions only exist on Windows' NTFS file system, and are typically
1289 created by the \c{mklink} command. They can be thought of as symlinks for
1290 directories, and can only be created for absolute paths on the local
1291 volume.
1292*/
1293bool QFileInfo::isJunction() const
1294{
1295 Q_D(const QFileInfo);
1296 return d->checkAttribute<bool>(
1297 QFileSystemMetaData::LegacyLinkType,
1298 [d]() { return d->metaData.isJunction(); },
1299 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1300}
1301
1302/*!
1303 Returns \c true if the object points to a directory or to a symbolic
1304 link to a directory, and that directory is the root directory; otherwise
1305 returns \c false.
1306*/
1307bool QFileInfo::isRoot() const
1308{
1309 Q_D(const QFileInfo);
1310 if (d->isDefaultConstructed)
1311 return false;
1312 if (d->fileEngine == nullptr) {
1313 if (d->fileEntry.isRoot()) {
1314#if defined(Q_OS_WIN)
1315 //the path is a drive root, but the drive may not exist
1316 //for backward compatibility, return true only if the drive exists
1317 if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute))
1318 QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute);
1319 return d->metaData.exists();
1320#else
1321 return true;
1322#endif
1323 }
1324 return false;
1325 }
1326 return d->getFileFlags(QAbstractFileEngine::RootFlag);
1327}
1328
1329/*!
1330 \since 4.2
1331
1332 Returns the absolute path to the file or directory a symbolic link
1333 points to, or an empty string if the object isn't a symbolic
1334 link.
1335
1336 This name may not represent an existing file; it is only a string.
1337
1338 \include qfileinfo.cpp symlink-target-exists-behavior
1339
1340 \sa exists(), isSymLink(), isDir(), isFile()
1341*/
1342QString QFileInfo::symLinkTarget() const
1343{
1344 Q_D(const QFileInfo);
1345 if (d->isDefaultConstructed)
1346 return ""_L1;
1347 return d->getFileName(QAbstractFileEngine::AbsoluteLinkTarget);
1348}
1349
1350/*!
1351 \since 6.6
1352 Read the path the symlink references.
1353
1354 Returns the raw path referenced by the symbolic link, without resolving a relative
1355 path relative to the directory containing the symbolic link. The returned string will
1356 only be an absolute path if the symbolic link actually references it as such. Returns
1357 an empty string if the object is not a symbolic link.
1358
1359 \sa symLinkTarget(), exists(), isSymLink(), isDir(), isFile()
1360*/
1361QString QFileInfo::readSymLink() const
1362{
1363 Q_D(const QFileInfo);
1364 if (d->isDefaultConstructed)
1365 return {};
1366 return d->getFileName(QAbstractFileEngine::RawLinkPath);
1367}
1368
1369/*!
1370 \since 6.2
1371
1372 Resolves an NTFS junction to the path it references.
1373
1374 Returns the absolute path to the directory an NTFS junction points to, or
1375 an empty string if the object is not an NTFS junction.
1376
1377 There is no guarantee that the directory named by the NTFS junction actually
1378 exists.
1379
1380 \sa isJunction(), isFile(), isDir(), isSymLink(), isSymbolicLink(),
1381 isShortcut()
1382*/
1383QString QFileInfo::junctionTarget() const
1384{
1385 Q_D(const QFileInfo);
1386 if (d->isDefaultConstructed)
1387 return ""_L1;
1388 return d->getFileName(QAbstractFileEngine::JunctionName);
1389}
1390
1391/*!
1392 Returns the owner of the file. On systems where files
1393 do not have owners, or if an error occurs, an empty string is
1394 returned.
1395
1396 This function can be time consuming under Unix (in the order of
1397 milliseconds). On Windows, it will return an empty string unless
1398 the \l{NTFS permissions} check has been enabled.
1399
1400 \include qfileinfo.cpp info-about-target-not-symlink
1401
1402 \sa ownerId(), group(), groupId()
1403*/
1404QString QFileInfo::owner() const
1405{
1406 Q_D(const QFileInfo);
1407 if (d->isDefaultConstructed)
1408 return ""_L1;
1409 return d->getFileOwner(QAbstractFileEngine::OwnerUser);
1410}
1411
1412/*!
1413 Returns the id of the owner of the file.
1414
1415 On Windows and on systems where files do not have owners this
1416 function returns ((uint) -2).
1417
1418 \include qfileinfo.cpp info-about-target-not-symlink
1419
1420 \sa owner(), group(), groupId()
1421*/
1422uint QFileInfo::ownerId() const
1423{
1424 Q_D(const QFileInfo);
1425 return d->checkAttribute(uint(-2),
1426 QFileSystemMetaData::UserId,
1427 [d]() { return d->metaData.userId(); },
1428 [d]() { return d->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); });
1429}
1430
1431/*!
1432 Returns the group of the file. On Windows, on systems where files
1433 do not have groups, or if an error occurs, an empty string is
1434 returned.
1435
1436 This function can be time consuming under Unix (in the order of
1437 milliseconds).
1438
1439 \include qfileinfo.cpp info-about-target-not-symlink
1440
1441 \sa groupId(), owner(), ownerId()
1442*/
1443QString QFileInfo::group() const
1444{
1445 Q_D(const QFileInfo);
1446 if (d->isDefaultConstructed)
1447 return ""_L1;
1448 return d->getFileOwner(QAbstractFileEngine::OwnerGroup);
1449}
1450
1451/*!
1452 Returns the id of the group the file belongs to.
1453
1454 On Windows and on systems where files do not have groups this
1455 function always returns (uint) -2.
1456
1457 \include qfileinfo.cpp info-about-target-not-symlink
1458
1459 \sa group(), owner(), ownerId()
1460*/
1461uint QFileInfo::groupId() const
1462{
1463 Q_D(const QFileInfo);
1464 return d->checkAttribute(uint(-2),
1465 QFileSystemMetaData::GroupId,
1466 [d]() { return d->metaData.groupId(); },
1467 [d]() { return d->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); });
1468}
1469
1470/*!
1471 Tests for file permissions. The \a permissions argument can be
1472 several flags of type QFile::Permissions OR-ed together to check
1473 for permission combinations.
1474
1475 On systems where files do not have permissions this function
1476 always returns \c true.
1477
1478 \note The result might be inaccurate on Windows if the
1479 \l{NTFS permissions} check has not been enabled.
1480
1481 Example:
1482 \snippet code/src_corelib_io_qfileinfo.cpp 10
1483
1484 \include qfileinfo.cpp info-about-target-not-symlink
1485
1486 \sa isReadable(), isWritable(), isExecutable()
1487*/
1488bool QFileInfo::permission(QFile::Permissions permissions) const
1489{
1490 Q_D(const QFileInfo);
1491 // the QFileSystemMetaData::MetaDataFlag and QFile::Permissions overlap, so just cast.
1492 auto fseFlags = QFileSystemMetaData::MetaDataFlags::fromInt(permissions.toInt());
1493 auto feFlags = QAbstractFileEngine::FileFlags::fromInt(permissions.toInt());
1494 return d->checkAttribute<bool>(
1495 fseFlags,
1496 [=]() { return (d->metaData.permissions() & permissions) == permissions; },
1497 [=]() {
1498 return d->getFileFlags(feFlags) == uint(permissions.toInt());
1499 });
1500}
1501
1502/*!
1503 Returns the complete OR-ed together combination of
1504 QFile::Permissions for the file.
1505
1506 \note The result might be inaccurate on Windows if the
1507 \l{NTFS permissions} check has not been enabled.
1508
1509 \include qfileinfo.cpp info-about-target-not-symlink
1510*/
1511QFile::Permissions QFileInfo::permissions() const
1512{
1513 Q_D(const QFileInfo);
1514 return d->checkAttribute<QFile::Permissions>(
1515 QFileSystemMetaData::Permissions,
1516 [d]() { return d->metaData.permissions(); },
1517 [d]() {
1518 return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask);
1519 });
1520}
1521
1522
1523/*!
1524 Returns the file size in bytes. If the file does not exist or cannot be
1525 fetched, 0 is returned.
1526
1527 \include qfileinfo.cpp info-about-target-not-symlink
1528
1529 \sa exists()
1530*/
1531qint64 QFileInfo::size() const
1532{
1533 Q_D(const QFileInfo);
1534 return d->checkAttribute<qint64>(
1535 QFileSystemMetaData::SizeAttribute,
1536 [d]() { return d->metaData.size(); },
1537 [d]() {
1538 if (!d->getCachedFlag(QFileInfoPrivate::CachedSize)) {
1539 d->setCachedFlag(QFileInfoPrivate::CachedSize);
1540 d->fileSize = d->fileEngine->size();
1541 }
1542 return d->fileSize;
1543 });
1544}
1545
1546/*!
1547 \fn QDateTime QFileInfo::birthTime() const
1548
1549 Returns the date and time when the file was created (born), in local time.
1550
1551 If the file birth time is not available, this function returns an invalid QDateTime.
1552
1553 \include qfileinfo.cpp info-about-target-not-symlink
1554
1555 This function overloads QFileInfo::birthTime(const QTimeZone &tz), and
1556 returns the same as \c{birthTime(QTimeZone::LocalTime)}.
1557
1558 \since 5.10
1559 \sa lastModified(), lastRead(), metadataChangeTime(), fileTime()
1560*/
1561
1562/*!
1563 \fn QDateTime QFileInfo::birthTime(const QTimeZone &tz) const
1564
1565 Returns the date and time when the file was created (born).
1566
1567 \include qfileinfo.cpp file-times-in-time-zone
1568
1569 If the file birth time is not available, this function returns an invalid
1570 QDateTime.
1571
1572 \include qfileinfo.cpp info-about-target-not-symlink
1573
1574 \since 6.6
1575 \sa lastModified(const QTimeZone &), lastRead(const QTimeZone &),
1576 metadataChangeTime(const QTimeZone &),
1577 fileTime(QFileDevice::FileTime, const QTimeZone &)
1578*/
1579
1580/*!
1581 \fn QDateTime QFileInfo::metadataChangeTime() const
1582
1583 Returns the date and time when the file's metadata was last changed,
1584 in local time.
1585
1586 A metadata change occurs when the file is first created, but it also
1587 occurs whenever the user writes or sets inode information (for example,
1588 changing the file permissions).
1589
1590 \include qfileinfo.cpp info-about-target-not-symlink
1591
1592 This function overloads QFileInfo::metadataChangeTime(const QTimeZone &tz),
1593 and returns the same as \c{metadataChangeTime(QTimeZone::LocalTime)}.
1594
1595 \since 5.10
1596 \sa birthTime(), lastModified(), lastRead(), fileTime()
1597*/
1598
1599/*!
1600 \fn QDateTime QFileInfo::metadataChangeTime(const QTimeZone &tz) const
1601
1602 Returns the date and time when the file's metadata was last changed.
1603 A metadata change occurs when the file is first created, but it also
1604 occurs whenever the user writes or sets inode information (for example,
1605 changing the file permissions).
1606
1607 \include qfileinfo.cpp file-times-in-time-zone
1608
1609 \include qfileinfo.cpp info-about-target-not-symlink
1610
1611 \since 6.6
1612 \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &),
1613 lastRead(const QTimeZone &),
1614 fileTime(QFileDevice::FileTime time, const QTimeZone &)
1615*/
1616
1617/*!
1618 \fn QDateTime QFileInfo::lastModified() const
1619
1620 Returns the date and time when the file was last modified.
1621
1622 \include qfileinfo.cpp info-about-target-not-symlink
1623
1624 This function overloads \l{QFileInfo::lastModified(const QTimeZone &)},
1625 and returns the same as \c{lastModified(QTimeZone::LocalTime)}.
1626
1627 \sa birthTime(), lastRead(), metadataChangeTime(), fileTime()
1628*/
1629
1630/*!
1631 \fn QDateTime QFileInfo::lastModified(const QTimeZone &tz) const
1632
1633 Returns the date and time when the file was last modified.
1634
1635 \include qfileinfo.cpp file-times-in-time-zone
1636
1637 \include qfileinfo.cpp info-about-target-not-symlink
1638
1639 \since 6.6
1640 \sa birthTime(const QTimeZone &), lastRead(const QTimeZone &),
1641 metadataChangeTime(const QTimeZone &),
1642 fileTime(QFileDevice::FileTime, const QTimeZone &)
1643*/
1644
1645/*!
1646 \fn QDateTime QFileInfo::lastRead() const
1647
1648 Returns the date and time when the file was last read (accessed).
1649
1650 On platforms where this information is not available, returns the same
1651 time as lastModified().
1652
1653 \include qfileinfo.cpp info-about-target-not-symlink
1654
1655 This function overloads \l{QFileInfo::lastRead(const QTimeZone &)},
1656 and returns the same as \c{lastRead(QTimeZone::LocalTime)}.
1657
1658 \sa birthTime(), lastModified(), metadataChangeTime(), fileTime()
1659*/
1660
1661/*!
1662 \fn QDateTime QFileInfo::lastRead(const QTimeZone &tz) const
1663
1664 Returns the date and time when the file was last read (accessed).
1665
1666 \include qfileinfo.cpp file-times-in-time-zone
1667
1668 On platforms where this information is not available, returns the same
1669 time as lastModified().
1670
1671 \include qfileinfo.cpp info-about-target-not-symlink
1672
1673 \since 6.6
1674 \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &),
1675 metadataChangeTime(const QTimeZone &),
1676 fileTime(QFileDevice::FileTime, const QTimeZone &)
1677*/
1678
1679#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
1680/*!
1681 Returns the file time specified by \a time.
1682
1683 If the time cannot be determined, an invalid date time is returned.
1684
1685 \include qfileinfo.cpp info-about-target-not-symlink
1686
1687 This function overloads
1688 \l{QFileInfo::fileTime(QFileDevice::FileTime, const QTimeZone &)},
1689 and returns the same as \c{fileTime(time, QTimeZone::LocalTime)}.
1690
1691 \since 5.10
1692 \sa birthTime(), lastModified(), lastRead(), metadataChangeTime()
1693*/
1694QDateTime QFileInfo::fileTime(QFile::FileTime time) const {
1695 return fileTime(time, QTimeZone::LocalTime);
1696}
1697#endif
1698
1699/*!
1700 Returns the file time specified by \a time.
1701
1702//! [file-times-in-time-zone]
1703 The returned time is in the time zone specified by \a tz. For example,
1704 you can use QTimeZone::LocalTime or QTimeZone::UTC to get the time in
1705 the Local time zone or UTC, respectively. Since native file system API
1706 typically uses UTC, using QTimeZone::UTC is often faster, as it does not
1707 require any conversions.
1708//! [file-times-in-time-zone]
1709
1710 If the time cannot be determined, an invalid date time is returned.
1711
1712 \include qfileinfo.cpp info-about-target-not-symlink
1713
1714 \since 6.6
1715 \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &),
1716 lastRead(const QTimeZone &), metadataChangeTime(const QTimeZone &),
1717 QDateTime::isValid()
1718*/
1719QDateTime QFileInfo::fileTime(QFile::FileTime time, const QTimeZone &tz) const
1720{
1721 Q_D(const QFileInfo);
1722 QFileSystemMetaData::MetaDataFlags flag;
1723 switch (time) {
1724 case QFile::FileAccessTime:
1725 flag = QFileSystemMetaData::AccessTime;
1726 break;
1727 case QFile::FileBirthTime:
1728 flag = QFileSystemMetaData::BirthTime;
1729 break;
1730 case QFile::FileMetadataChangeTime:
1731 flag = QFileSystemMetaData::MetadataChangeTime;
1732 break;
1733 case QFile::FileModificationTime:
1734 flag = QFileSystemMetaData::ModificationTime;
1735 break;
1736 }
1737
1738 auto fsLambda = [d, time]() { return d->metaData.fileTime(time); };
1739 auto engineLambda = [d, time]() { return d->getFileTime(time); };
1740 const auto dt =
1741 d->checkAttribute<QDateTime>(flag, std::move(fsLambda), std::move(engineLambda));
1742 return dt.toTimeZone(tz);
1743}
1744
1745/*!
1746 \internal
1747*/
1748QFileInfoPrivate* QFileInfo::d_func()
1749{
1750 return d_ptr.data();
1751}
1752
1753/*!
1754 Returns \c true if caching is enabled; otherwise returns \c false.
1755
1756 \sa setCaching(), refresh()
1757*/
1758bool QFileInfo::caching() const
1759{
1760 Q_D(const QFileInfo);
1761 return d->cache_enabled;
1762}
1763
1764/*!
1765 If \a enable is true, enables caching of file information. If \a
1766 enable is false caching is disabled.
1767
1768 When caching is enabled, QFileInfo reads the file information from
1769 the file system the first time it's needed, but generally not
1770 later.
1771
1772 Caching is enabled by default.
1773
1774 \sa refresh(), caching()
1775*/
1776void QFileInfo::setCaching(bool enable)
1777{
1778 Q_D(QFileInfo);
1779 d->cache_enabled = enable;
1780}
1781
1782/*!
1783 Reads all attributes from the file system.
1784 \since 6.0
1785
1786 This is useful when information about the file system is collected in a
1787 worker thread, and then passed to the UI in the form of caching QFileInfo
1788 instances.
1789
1790 \sa setCaching(), refresh()
1791*/
1792void QFileInfo::stat()
1793{
1794 Q_D(QFileInfo);
1795 QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::AllMetaDataFlags);
1796}
1797
1798/*!
1799 \typedef QFileInfoList
1800 \relates QFileInfo
1801
1802 Synonym for QList<QFileInfo>.
1803*/
1804
1805#ifndef QT_NO_DEBUG_STREAM
1806QDebug operator<<(QDebug dbg, const QFileInfo &fi)
1807{
1808 QDebugStateSaver saver(dbg);
1809 dbg.nospace();
1810 dbg.noquote();
1811 dbg << "QFileInfo(" << QDir::toNativeSeparators(fi.filePath()) << ')';
1812 return dbg;
1813}
1814#endif
1815
1816/*!
1817 \fn QFileInfo::QFileInfo(const std::filesystem::path &file)
1818 \since 6.0
1819
1820 Constructs a new QFileInfo that gives information about the given
1821 \a file.
1822
1823 \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
1824*/
1825/*!
1826 \fn QFileInfo::QFileInfo(const QDir &dir, const std::filesystem::path &path)
1827 \since 6.0
1828
1829 Constructs a new QFileInfo that gives information about the file system
1830 entry at \a path that is relative to the directory \a dir.
1831
1832 \include qfileinfo.cpp preserve-relative-or-absolute
1833*/
1834/*!
1835 \fn void QFileInfo::setFile(const std::filesystem::path &path)
1836 \since 6.0
1837
1838 Sets the path of file system entry that this QFileInfo provides
1839 information about to \a path.
1840
1841 \include qfileinfo.cpp preserve-relative-path
1842*/
1843/*!
1844 \fn std::filesystem::path QFileInfo::filesystemFilePath() const
1845 \since 6.0
1846
1847 Returns filePath() as a \c{std::filesystem::path}.
1848 \sa filePath()
1849*/
1850/*!
1851 \fn std::filesystem::path QFileInfo::filesystemAbsoluteFilePath() const
1852 \since 6.0
1853
1854 Returns absoluteFilePath() as a \c{std::filesystem::path}.
1855 \sa absoluteFilePath()
1856*/
1857/*!
1858 \fn std::filesystem::path QFileInfo::filesystemCanonicalFilePath() const
1859 \since 6.0
1860
1861 Returns canonicalFilePath() as a \c{std::filesystem::path}.
1862 \sa canonicalFilePath()
1863*/
1864/*!
1865 \fn std::filesystem::path QFileInfo::filesystemPath() const
1866 \since 6.0
1867
1868 Returns path() as a \c{std::filesystem::path}.
1869 \sa path()
1870*/
1871/*!
1872 \fn std::filesystem::path QFileInfo::filesystemAbsolutePath() const
1873 \since 6.0
1874
1875 Returns absolutePath() as a \c{std::filesystem::path}.
1876 \sa absolutePath()
1877*/
1878/*!
1879 \fn std::filesystem::path QFileInfo::filesystemCanonicalPath() const
1880 \since 6.0
1881
1882 Returns canonicalPath() as a \c{std::filesystem::path}.
1883 \sa canonicalPath()
1884*/
1885/*!
1886 \fn std::filesystem::path QFileInfo::filesystemSymLinkTarget() const
1887 \since 6.0
1888
1889 Returns symLinkTarget() as a \c{std::filesystem::path}.
1890 \sa symLinkTarget()
1891*/
1892/*!
1893 \fn std::filesystem::path QFileInfo::filesystemReadSymLink() const
1894 \since 6.6
1895
1896 Returns readSymLink() as a \c{std::filesystem::path}.
1897 \sa readSymLink()
1898*/
1899/*!
1900 \fn std::filesystem::path QFileInfo::filesystemJunctionTarget() const
1901 \since 6.2
1902
1903 Returns junctionTarget() as a \c{std::filesystem::path}.
1904 \sa junctionTarget()
1905*/
1906/*!
1907 \macro QT_IMPLICIT_QFILEINFO_CONSTRUCTION
1908 \since 6.0
1909 \relates QFileInfo
1910
1911 Defining this macro makes most QFileInfo constructors implicit
1912 instead of explicit. Since construction of QFileInfo objects is
1913 expensive, one should avoid accidentally creating them, especially
1914 if cheaper alternatives exist. For instance:
1915
1916 \badcode
1917
1918 QDirIterator it(dir);
1919 while (it.hasNext()) {
1920 // Implicit conversion from QString (returned by it.next()):
1921 // may create unnecessary data structures and cause additional
1922 // accesses to the file system. Unless this macro is defined,
1923 // this line does not compile.
1924
1925 QFileInfo fi = it.next();
1926
1927 ~~~
1928 }
1929
1930 \endcode
1931
1932 Instead, use the right API:
1933
1934 \code
1935
1936 QDirIterator it(dir);
1937 while (it.hasNext()) {
1938 // Extract the QFileInfo from the iterator directly:
1939 QFileInfo fi = it.nextFileInfo();
1940
1941 ~~~
1942 }
1943
1944 \endcode
1945
1946 Construction from QString, QFile, and so on is always possible by
1947 using direct initialization instead of copy initialization:
1948
1949 \code
1950
1951 QFileInfo fi1 = some_string; // Does not compile unless this macro is defined
1952 QFileInfo fi2(some_string); // OK
1953 QFileInfo fi3{some_string}; // Possibly better, avoids the risk of the Most Vexing Parse
1954 auto fi4 = QFileInfo(some_string); // OK
1955
1956 \endcode
1957
1958 This macro is provided for compatibility reason. Its usage is not
1959 recommended in new code.
1960*/
1961
1962QT_END_NAMESPACE
QDateTime & getFileTime(QFile::FileTime) const
uint getFileFlags(QAbstractFileEngine::FileFlags) const
Definition qfileinfo.cpp:99
void clearFlags() const
QString getFileOwner(QAbstractFileEngine::FileOwner own) const
Definition qfileinfo.cpp:75
Combined button and popup list for selecting options.
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)