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