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