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 This method returns an empty string if the entry does not exist, is not
611 reachable (for example, the current user does not have access to a
612 directory path), or an error occurs while canonicalizing the path (normally
613 due to dangling symbolic links).
614
615 \sa filePath(), absoluteFilePath(), dir()
616*/
617QString QFileInfo::canonicalFilePath() const
618{
619 Q_D(const QFileInfo);
620 if (d->isDefaultConstructed)
621 return ""_L1;
622 return d->getFileName(QAbstractFileEngine::CanonicalName);
623}
624
625
626/*!
627 Returns the absolute path of the file system entry this QFileInfo refers to,
628 excluding the entry's name.
629
630 \include qfileinfo.cpp absolute-path-unix-windows
631
632 \include qfileinfo.cpp windows-network-shares
633
634 In contrast to canonicalPath() symbolic links or redundant "." or
635 ".." elements are not necessarily removed.
636
637 \warning If filePath() is empty the behavior of this function
638 is undefined.
639
640 \sa absoluteFilePath(), path(), canonicalPath(), fileName(), isRelative()
641*/
642QString QFileInfo::absolutePath() const
643{
644 Q_D(const QFileInfo);
645
646 if (d->isDefaultConstructed)
647 return ""_L1;
648 return d->getFileName(QAbstractFileEngine::AbsolutePathName);
649}
650
651/*!
652 Returns the file system entry's canonical path (excluding the entry's name),
653 i.e. an absolute path without symbolic links or redundant "." or ".." elements.
654
655 This method returns an empty string if the entry does not exist, is not
656 reachable (for example, the current user does not have access to a
657 directory path), or an error occurs while canonicalizing the path (normally
658 due to dangling symbolic links).
659
660 \sa path(), absolutePath()
661*/
662QString QFileInfo::canonicalPath() const
663{
664 Q_D(const QFileInfo);
665 if (d->isDefaultConstructed)
666 return ""_L1;
667 return d->getFileName(QAbstractFileEngine::CanonicalPathName);
668}
669
670/*!
671 Returns the path of the file system entry this QFileInfo refers to,
672 excluding the entry's name.
673
674 \include qfileinfo.cpp path-ends-with-slash-empty-name-component
675 In this case, this function will return the entire path.
676
677 \sa filePath(), absolutePath(), canonicalPath(), dir(), fileName(), isRelative()
678*/
679QString QFileInfo::path() const
680{
681 Q_D(const QFileInfo);
682 if (d->isDefaultConstructed)
683 return ""_L1;
684 return d->fileEntry.path();
685}
686
687/*!
688 \fn bool QFileInfo::isAbsolute() const
689
690 Returns \c true if the file system entry's path is absolute, otherwise
691 returns \c false (that is, the path is relative).
692
693 \include qfileinfo.cpp qresource-virtual-fs-colon
694
695 \sa isRelative()
696*/
697
698/*!
699 Returns \c true if the file system entry's path is relative, otherwise
700 returns \c false (that is, the path is absolute).
701
702 \include qfileinfo.cpp absolute-path-unix-windows
703
704 \include qfileinfo.cpp qresource-virtual-fs-colon
705
706 \sa isAbsolute()
707*/
708bool QFileInfo::isRelative() const
709{
710 Q_D(const QFileInfo);
711 if (d->isDefaultConstructed)
712 return true;
713 if (d->fileEngine == nullptr)
714 return d->fileEntry.isRelative();
715 return d->fileEngine->isRelativePath();
716}
717
718/*!
719 If the file system entry's path is relative, this method converts it to
720 an absolute path and returns \c true; if the path is already absolute,
721 this method returns \c false.
722
723 \sa filePath(), isRelative()
724*/
725bool QFileInfo::makeAbsolute()
726{
727 if (d_ptr.constData()->isDefaultConstructed
728 || !d_ptr.constData()->fileEntry.isRelative())
729 return false;
730
731 setFile(absoluteFilePath());
732 return true;
733}
734
735/*!
736 Returns \c true if the file system entry this QFileInfo refers to exists;
737 otherwise returns \c false.
738
739 \note If the entry is a symlink that points to a non-existing
740 target, this method returns \c false.
741*/
742bool QFileInfo::exists() const
743{
744 Q_D(const QFileInfo);
745 if (d->isDefaultConstructed)
746 return false;
747 if (d->fileEngine == nullptr) {
748 if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute))
749 QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute);
750 return d->metaData.exists();
751 }
752 return d->getFileFlags(QAbstractFileEngine::ExistsFlag);
753}
754
755/*!
756 \since 5.2
757
758 Returns \c true if the file system entry \a path exists; otherwise
759 returns \c false.
760
761 \note If \a path is a symlink that points to a non-existing
762 target, this method returns \c false.
763
764 \note Using this function is faster than using
765 \c QFileInfo(path).exists() for file system access.
766*/
767bool QFileInfo::exists(const QString &path)
768{
769 if (path.isEmpty())
770 return false;
771 QFileSystemEntry entry(path);
772 QFileSystemMetaData data;
773 // Expensive fallback to non-QFileSystemEngine implementation
774 if (auto engine = QFileSystemEngine::createLegacyEngine(entry, data))
775 return QFileInfo(new QFileInfoPrivate(entry, data, std::move(engine))).exists();
776
777 QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
778 return data.exists();
779}
780
781/*!
782 Refreshes the information about the file system entry this QFileInfo
783 refers to, that is, reads in information from the file system the next
784 time a cached property is fetched.
785*/
786void QFileInfo::refresh()
787{
788 Q_D(QFileInfo);
789 d->clear();
790}
791
792/*!
793 Returns the path of the file system entry this QFileInfo refers to;
794 the path may be absolute or relative.
795
796 \sa absoluteFilePath(), canonicalFilePath(), isRelative()
797*/
798QString QFileInfo::filePath() const
799{
800 Q_D(const QFileInfo);
801 if (d->isDefaultConstructed)
802 return ""_L1;
803 return d->fileEntry.filePath();
804}
805
806/*!
807 Returns the name of the file system entry this QFileInfo refers to,
808 excluding the path.
809
810 Example:
811 \snippet code/src_corelib_io_qfileinfo.cpp 3
812
813//! [path-ends-with-slash-empty-name-component]
814 \note If this QFileInfo is given a path ending with a directory separator
815 \c{'/'}, the entry's name part is considered empty.
816//! [path-ends-with-slash-empty-name-component]
817
818 \sa isRelative(), filePath(), baseName(), suffix()
819*/
820QString QFileInfo::fileName() const
821{
822 Q_D(const QFileInfo);
823 if (d->isDefaultConstructed)
824 return ""_L1;
825 if (!d->fileEngine)
826 return d->fileEntry.fileName();
827 return d->fileEngine->fileName(QAbstractFileEngine::BaseName);
828}
829
830/*!
831 \since 4.3
832 Returns the name of the bundle.
833
834 On \macos and iOS this returns the proper localized name for a bundle if the
835 path isBundle(). On all other platforms an empty QString is returned.
836
837 Example:
838 \snippet code/src_corelib_io_qfileinfo.cpp 4
839
840 \sa isBundle(), filePath(), baseName(), suffix()
841*/
842QString QFileInfo::bundleName() const
843{
844 Q_D(const QFileInfo);
845 if (d->isDefaultConstructed)
846 return ""_L1;
847 return d->getFileName(QAbstractFileEngine::BundleName);
848}
849
850/*!
851 Returns the base name of the file without the path.
852
853 The base name consists of all characters in the file up to (but
854 not including) the \e first '.' character.
855
856 Example:
857 \snippet code/src_corelib_io_qfileinfo.cpp 5
858
859
860 The base name of a file is computed equally on all platforms, independent
861 of file naming conventions (e.g., ".bashrc" on Unix has an empty base
862 name, and the suffix is "bashrc").
863
864 \sa fileName(), suffix(), completeSuffix(), completeBaseName()
865*/
866QString QFileInfo::baseName() const
867{
868 Q_D(const QFileInfo);
869 if (d->isDefaultConstructed)
870 return ""_L1;
871 if (!d->fileEngine)
872 return d->fileEntry.baseName();
873 return QFileSystemEntry(d->fileEngine->fileName(QAbstractFileEngine::BaseName)).baseName();
874}
875
876/*!
877 Returns the complete base name of the file without the path.
878
879 The complete base name consists of all characters in the file up
880 to (but not including) the \e last '.' character.
881
882 Example:
883 \snippet code/src_corelib_io_qfileinfo.cpp 6
884
885 \sa fileName(), suffix(), completeSuffix(), baseName()
886*/
887QString QFileInfo::completeBaseName() const
888{
889 Q_D(const QFileInfo);
890 if (d->isDefaultConstructed)
891 return ""_L1;
892 if (!d->fileEngine)
893 return d->fileEntry.completeBaseName();
894 const QString fileEngineBaseName = d->fileEngine->fileName(QAbstractFileEngine::BaseName);
895 return QFileSystemEntry(fileEngineBaseName).completeBaseName();
896}
897
898/*!
899 Returns the complete suffix (extension) of the file.
900
901 The complete suffix consists of all characters in the file after
902 (but not including) the first '.'.
903
904 Example:
905 \snippet code/src_corelib_io_qfileinfo.cpp 7
906
907 \sa fileName(), suffix(), baseName(), completeBaseName()
908*/
909QString QFileInfo::completeSuffix() const
910{
911 Q_D(const QFileInfo);
912 if (d->isDefaultConstructed)
913 return ""_L1;
914 return d->fileEntry.completeSuffix();
915}
916
917/*!
918 Returns the suffix (extension) of the file.
919
920 The suffix consists of all characters in the file after (but not
921 including) the last '.'.
922
923 Example:
924 \snippet code/src_corelib_io_qfileinfo.cpp 8
925
926 The suffix of a file is computed equally on all platforms, independent of
927 file naming conventions (e.g., ".bashrc" on Unix has an empty base name,
928 and the suffix is "bashrc").
929
930 \sa fileName(), completeSuffix(), baseName(), completeBaseName()
931*/
932QString QFileInfo::suffix() const
933{
934 Q_D(const QFileInfo);
935 if (d->isDefaultConstructed)
936 return ""_L1;
937 return d->fileEntry.suffix();
938}
939
940
941/*!
942 Returns a QDir object representing the path of the parent directory of the
943 file system entry that this QFileInfo refers to.
944
945 \note The QDir returned always corresponds to the object's
946 parent directory, even if the QFileInfo represents a directory.
947
948 For each of the following, dir() returns the QDir
949 \c{"~/examples/191697"}.
950
951 \snippet fileinfo/main.cpp 0
952
953 For each of the following, dir() returns the QDir
954 \c{"."}.
955
956 \snippet fileinfo/main.cpp 1
957
958 \sa absolutePath(), filePath(), fileName(), isRelative(), absoluteDir()
959*/
960QDir QFileInfo::dir() const
961{
962 Q_D(const QFileInfo);
963 return QDir(d->fileEntry.path());
964}
965
966/*!
967 Returns a QDir object representing the absolute path of the parent
968 directory of the file system entry that this QFileInfo refers to.
969
970 \snippet code/src_corelib_io_qfileinfo.cpp 11
971
972 \sa dir(), filePath(), fileName(), isRelative()
973*/
974QDir QFileInfo::absoluteDir() const
975{
976 return QDir(absolutePath());
977}
978
979/*!
980 Returns \c true if the user can read the file system entry this QFileInfo
981 refers to; otherwise returns \c false.
982
983 \include qfileinfo.cpp info-about-target-not-symlink
984
985 \note If the \l{NTFS permissions} check has not been enabled, the result
986 on Windows will merely reflect whether the entry exists.
987
988 \sa isWritable(), isExecutable(), permission()
989*/
990bool QFileInfo::isReadable() const
991{
992 Q_D(const QFileInfo);
993 return d->checkAttribute<bool>(
994 QFileSystemMetaData::UserReadPermission,
995 [d]() { return d->metaData.isReadable(); },
996 [d]() { return d->getFileFlags(QAbstractFileEngine::ReadUserPerm); });
997}
998
999/*!
1000 Returns \c true if the user can write to the file system entry this
1001 QFileInfo refers to; otherwise returns \c false.
1002
1003 \include qfileinfo.cpp info-about-target-not-symlink
1004
1005 \note If the \l{NTFS permissions} check has not been enabled, the result on
1006 Windows will merely reflect whether the entry is marked as Read Only.
1007
1008 \sa isReadable(), isExecutable(), permission()
1009*/
1010bool QFileInfo::isWritable() const
1011{
1012 Q_D(const QFileInfo);
1013 return d->checkAttribute<bool>(
1014 QFileSystemMetaData::UserWritePermission,
1015 [d]() { return d->metaData.isWritable(); },
1016 [d]() { return d->getFileFlags(QAbstractFileEngine::WriteUserPerm); });
1017}
1018
1019/*!
1020 Returns \c true if the file system entry this QFileInfo refers to is
1021 executable; otherwise returns \c false.
1022
1023//! [info-about-target-not-symlink]
1024 If the file is a symlink, this function returns information about the
1025 target, not the symlink.
1026//! [info-about-target-not-symlink]
1027
1028 \sa isReadable(), isWritable(), permission()
1029*/
1030bool QFileInfo::isExecutable() const
1031{
1032 Q_D(const QFileInfo);
1033 return d->checkAttribute<bool>(
1034 QFileSystemMetaData::UserExecutePermission,
1035 [d]() { return d->metaData.isExecutable(); },
1036 [d]() { return d->getFileFlags(QAbstractFileEngine::ExeUserPerm); });
1037}
1038
1039/*!
1040 Returns \c true if the file system entry this QFileInfo refers to is
1041 `hidden'; otherwise returns \c false.
1042
1043 \b{Note:} This function returns \c true for the special entries "." and
1044 ".." on Unix, even though QDir::entryList treats them as shown. And note
1045 that, since this function inspects the file name, on Unix it will inspect
1046 the name of the symlink, if this file is a symlink, not the target's name.
1047
1048 On Windows, this function returns \c true if the target file is hidden (not
1049 the symlink).
1050*/
1051bool QFileInfo::isHidden() const
1052{
1053 Q_D(const QFileInfo);
1054 return d->checkAttribute<bool>(
1055 QFileSystemMetaData::HiddenAttribute,
1056 [d]() { return d->metaData.isHidden(); },
1057 [d]() { return d->getFileFlags(QAbstractFileEngine::HiddenFlag); });
1058}
1059
1060/*!
1061 \since 5.0
1062 Returns \c true if the file path can be used directly with native APIs.
1063 Returns \c false if the file is otherwise supported by a virtual file system
1064 inside Qt, such as \l{the Qt Resource System}.
1065
1066 \b{Note:} Native paths may still require conversion of path separators
1067 and character encoding, depending on platform and input requirements of the
1068 native API.
1069
1070 \sa QDir::toNativeSeparators(), QFile::encodeName(), filePath(),
1071 absoluteFilePath(), canonicalFilePath()
1072*/
1073bool QFileInfo::isNativePath() const
1074{
1075 Q_D(const QFileInfo);
1076 if (d->isDefaultConstructed)
1077 return false;
1078 if (d->fileEngine == nullptr)
1079 return true;
1080 return d->getFileFlags(QAbstractFileEngine::LocalDiskFlag);
1081}
1082
1083/*!
1084 Returns \c true if this object points to a file or to a symbolic
1085 link to a file. Returns \c false if the
1086 object points to something that is not a file (such as a directory)
1087 or that does not exist.
1088
1089 \include qfileinfo.cpp info-about-target-not-symlink
1090
1091 \sa isDir(), isSymLink(), isBundle()
1092*/
1093bool QFileInfo::isFile() const
1094{
1095 Q_D(const QFileInfo);
1096 return d->checkAttribute<bool>(
1097 QFileSystemMetaData::FileType,
1098 [d]() { return d->metaData.isFile(); },
1099 [d]() { return d->getFileFlags(QAbstractFileEngine::FileType); });
1100}
1101
1102/*!
1103 Returns \c true if this object points to a directory or to a symbolic
1104 link to a directory. Returns \c false if the
1105 object points to something that is not a directory (such as a file)
1106 or that does not exist.
1107
1108 \include qfileinfo.cpp info-about-target-not-symlink
1109
1110 \sa isFile(), isSymLink(), isBundle()
1111*/
1112bool QFileInfo::isDir() const
1113{
1114 Q_D(const QFileInfo);
1115 return d->checkAttribute<bool>(
1116 QFileSystemMetaData::DirectoryType,
1117 [d]() { return d->metaData.isDirectory(); },
1118 [d]() { return d->getFileFlags(QAbstractFileEngine::DirectoryType); });
1119}
1120
1121
1122/*!
1123 \since 4.3
1124 Returns \c true if this object points to a bundle or to a symbolic
1125 link to a bundle on \macos and iOS; otherwise returns \c false.
1126
1127 \include qfileinfo.cpp info-about-target-not-symlink
1128
1129 \sa isDir(), isSymLink(), isFile()
1130*/
1131bool QFileInfo::isBundle() const
1132{
1133 Q_D(const QFileInfo);
1134 return d->checkAttribute<bool>(
1135 QFileSystemMetaData::BundleType,
1136 [d]() { return d->metaData.isBundle(); },
1137 [d]() { return d->getFileFlags(QAbstractFileEngine::BundleType); });
1138}
1139
1140/*!
1141 Returns \c true if this object points to a symbolic link, shortcut,
1142 or alias; otherwise returns \c false.
1143
1144 Symbolic links exist on Unix (including \macos and iOS) and Windows
1145 and are typically created by the \c{ln -s} or \c{mklink} commands,
1146 respectively. Opening a symbolic link effectively opens
1147 the \l{symLinkTarget()}{link's target}.
1148
1149 In addition, true will be returned for shortcuts (\c *.lnk files) on
1150 Windows, and aliases on \macos. This behavior is deprecated and will
1151 likely change in a future version of Qt. Opening a shortcut or alias
1152 will open the \c .lnk or alias file itself.
1153
1154 Example:
1155
1156 \snippet code/src_corelib_io_qfileinfo.cpp 9
1157
1158//! [symlink-target-exists-behavior]
1159 \note exists() returns \c true if the symlink points to an existing
1160 target, otherwise it returns \c false.
1161//! [symlink-target-exists-behavior]
1162
1163 \sa isFile(), isDir(), symLinkTarget()
1164*/
1165bool QFileInfo::isSymLink() const
1166{
1167 Q_D(const QFileInfo);
1168 return d->checkAttribute<bool>(
1169 QFileSystemMetaData::LegacyLinkType,
1170 [d]() { return d->metaData.isLegacyLink(); },
1171 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1172}
1173
1174/*!
1175 Returns \c true if this object points to a symbolic link;
1176 otherwise returns \c false.
1177
1178 Symbolic links exist on Unix (including \macos and iOS) and Windows
1179 (NTFS-symlink) and are typically created by the \c{ln -s} or \c{mklink}
1180 commands, respectively.
1181
1182 Unix handles symlinks transparently. Opening a symbolic link effectively
1183 opens the \l{symLinkTarget()}{link's target}.
1184
1185 In contrast to isSymLink(), false will be returned for shortcuts
1186 (\c *.lnk files) on Windows and aliases on \macos. Use QFileInfo::isShortcut()
1187 and QFileInfo::isAlias() instead.
1188
1189 \include qfileinfo.cpp symlink-target-exists-behavior
1190
1191 \sa isFile(), isDir(), isShortcut(), symLinkTarget()
1192*/
1193
1194bool QFileInfo::isSymbolicLink() const
1195{
1196 Q_D(const QFileInfo);
1197 return d->checkAttribute<bool>(
1198 QFileSystemMetaData::LegacyLinkType,
1199 [d]() { return d->metaData.isLink(); },
1200 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1201}
1202
1203/*!
1204 \since 6.10
1205
1206 Returns \c true if this QFileInfo refers to a file system entry that is
1207 \e not a directory, regular file or symbolic link. Otherwise returns
1208 \c false.
1209
1210 If this QFileInfo refers to a nonexistent entry, this method returns
1211 \c false.
1212
1213 If the entry is a dangling symbolic link (the target doesn't exist), this
1214 method returns \c false. For a non-dangling symbolic link, this function
1215 returns information about the target, not the symbolic link.
1216
1217 On Unix a special (other) file system entry is a FIFO, socket, character
1218 device, or block device. For more details, see the
1219 \l{https://pubs.opengroup.org/onlinepubs/9699919799/functions/mknod.html}{\c mknod}
1220 manual page.
1221
1222 On Windows (for historical reasons, see \l{Symbolic Links and Shortcuts})
1223 this method returns \c true for \c .lnk files.
1224
1225 \sa isDir(), isFile(), isSymLink(), QDirListing::IteratorFlag::ExcludeOther
1226*/
1227bool QFileInfo::isOther() const
1228{
1229 Q_D(const QFileInfo);
1230 using M = QFileSystemMetaData::MetaDataFlag;
1231 // No M::LinkType to make QFileSystemEngine always call stat().
1232 // M::WinLnkType is only relevant on Windows for '.lnk' files
1233 constexpr auto mdFlags = M::ExistsAttribute | M::DirectoryType | M::FileType | M::WinLnkType;
1234
1235 auto fsLambda = [d]() {
1236 // Check isLnkFile() first because currently exists() returns false for
1237 // a broken '.lnk' where the target doesn't exist.
1238 if (d->metaData.isLnkFile()) // Always false on non-Windows OSes
1239 return true;
1240 return d->metaData.exists() && !d->metaData.isDirectory() && !d->metaData.isFile();
1241 };
1242
1243 auto engineLambda = [d]() {
1244 using F = QAbstractFileEngine::FileFlag;
1245 return d->getFileFlags(F::ExistsFlag)
1246 && !d->getFileFlags(F::LinkType) // QAFE doesn't have a separate type for ".lnk" file
1247 && !d->getFileFlags(F::DirectoryType)
1248 && !d->getFileFlags(F::FileType);
1249 };
1250
1251 return d->checkAttribute<bool>(mdFlags, std::move(fsLambda), std::move(engineLambda));
1252}
1253
1254/*!
1255 Returns \c true if this object points to a shortcut;
1256 otherwise returns \c false.
1257
1258 Shortcuts only exist on Windows and are typically \c .lnk files.
1259 For instance, true will be returned for shortcuts (\c *.lnk files) on
1260 Windows, but false will be returned on Unix (including \macos and iOS).
1261
1262 The shortcut (.lnk) files are treated as regular files. Opening those will
1263 open the \c .lnk file itself. In order to open the file a shortcut
1264 references to, it must uses symLinkTarget() on a shortcut.
1265
1266 \note Even if a shortcut (broken shortcut) points to a non existing file,
1267 isShortcut() returns true.
1268
1269 \sa isFile(), isDir(), isSymbolicLink(), symLinkTarget()
1270*/
1271bool QFileInfo::isShortcut() const
1272{
1273 Q_D(const QFileInfo);
1274 return d->checkAttribute<bool>(
1275 QFileSystemMetaData::LegacyLinkType,
1276 [d]() { return d->metaData.isLnkFile(); },
1277 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1278}
1279
1280/*!
1281 Returns \c true if this object points to an alias;
1282 otherwise returns \c false.
1283
1284 \since 6.4
1285
1286 Aliases only exist on \macos. They are treated as regular files, so
1287 opening an alias will open the file itself. In order to open the file
1288 or directory an alias references use symLinkTarget().
1289
1290 \note Even if an alias points to a non existing file,
1291 isAlias() returns true.
1292
1293 \sa isFile(), isDir(), isSymLink(), symLinkTarget()
1294*/
1295bool QFileInfo::isAlias() const
1296{
1297 Q_D(const QFileInfo);
1298 return d->checkAttribute<bool>(
1299 QFileSystemMetaData::LegacyLinkType,
1300 [d]() { return d->metaData.isAlias(); },
1301 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1302}
1303
1304/*!
1305 \since 5.15
1306
1307 Returns \c true if the object points to a junction;
1308 otherwise returns \c false.
1309
1310 Junctions only exist on Windows' NTFS file system, and are typically
1311 created by the \c{mklink} command. They can be thought of as symlinks for
1312 directories, and can only be created for absolute paths on the local
1313 volume.
1314*/
1315bool QFileInfo::isJunction() const
1316{
1317 Q_D(const QFileInfo);
1318 return d->checkAttribute<bool>(
1319 QFileSystemMetaData::LegacyLinkType,
1320 [d]() { return d->metaData.isJunction(); },
1321 [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); });
1322}
1323
1324/*!
1325 Returns \c true if the object points to a directory or to a symbolic
1326 link to a directory, and that directory is the root directory; otherwise
1327 returns \c false.
1328*/
1329bool QFileInfo::isRoot() const
1330{
1331 Q_D(const QFileInfo);
1332 if (d->isDefaultConstructed)
1333 return false;
1334 if (d->fileEngine == nullptr) {
1335 if (d->fileEntry.isRoot()) {
1336#if defined(Q_OS_WIN)
1337 //the path is a drive root, but the drive may not exist
1338 //for backward compatibility, return true only if the drive exists
1339 if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute))
1340 QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::ExistsAttribute);
1341 return d->metaData.exists();
1342#else
1343 return true;
1344#endif
1345 }
1346 return false;
1347 }
1348 return d->getFileFlags(QAbstractFileEngine::RootFlag);
1349}
1350
1351/*!
1352 \since 4.2
1353
1354 Returns the absolute path to the file or directory a symbolic link
1355 points to, or an empty string if the object isn't a symbolic
1356 link.
1357
1358 This name may not represent an existing file; it is only a string.
1359
1360 \include qfileinfo.cpp symlink-target-exists-behavior
1361
1362 \sa exists(), isSymLink(), isDir(), isFile()
1363*/
1364QString QFileInfo::symLinkTarget() const
1365{
1366 Q_D(const QFileInfo);
1367 if (d->isDefaultConstructed)
1368 return ""_L1;
1369 return d->getFileName(QAbstractFileEngine::AbsoluteLinkTarget);
1370}
1371
1372/*!
1373 \since 6.6
1374 Read the path the symlink references.
1375
1376 Returns the raw path referenced by the symbolic link, without resolving a relative
1377 path relative to the directory containing the symbolic link. The returned string will
1378 only be an absolute path if the symbolic link actually references it as such. Returns
1379 an empty string if the object is not a symbolic link.
1380
1381 \sa symLinkTarget(), exists(), isSymLink(), isDir(), isFile()
1382*/
1383QString QFileInfo::readSymLink() const
1384{
1385 Q_D(const QFileInfo);
1386 if (d->isDefaultConstructed)
1387 return {};
1388 return d->getFileName(QAbstractFileEngine::RawLinkPath);
1389}
1390
1391/*!
1392 \since 6.2
1393
1394 Resolves an NTFS junction to the path it references.
1395
1396 Returns the absolute path to the directory an NTFS junction points to, or
1397 an empty string if the object is not an NTFS junction.
1398
1399 There is no guarantee that the directory named by the NTFS junction actually
1400 exists.
1401
1402 \sa isJunction(), isFile(), isDir(), isSymLink(), isSymbolicLink(),
1403 isShortcut()
1404*/
1405QString QFileInfo::junctionTarget() const
1406{
1407 Q_D(const QFileInfo);
1408 if (d->isDefaultConstructed)
1409 return ""_L1;
1410 return d->getFileName(QAbstractFileEngine::JunctionName);
1411}
1412
1413/*!
1414 Returns the owner of the file. On systems where files
1415 do not have owners, or if an error occurs, an empty string is
1416 returned.
1417
1418 This function can be time consuming under Unix (in the order of
1419 milliseconds). On Windows, it will return an empty string unless
1420 the \l{NTFS permissions} check has been enabled.
1421
1422 \include qfileinfo.cpp info-about-target-not-symlink
1423
1424 \sa ownerId(), group(), groupId()
1425*/
1426QString QFileInfo::owner() const
1427{
1428 Q_D(const QFileInfo);
1429 if (d->isDefaultConstructed)
1430 return ""_L1;
1431 return d->getFileOwner(QAbstractFileEngine::OwnerUser);
1432}
1433
1434/*!
1435 Returns the id of the owner of the file.
1436
1437 On Windows and on systems where files do not have owners this
1438 function returns ((uint) -2).
1439
1440 \include qfileinfo.cpp info-about-target-not-symlink
1441
1442 \sa owner(), group(), groupId()
1443*/
1444uint QFileInfo::ownerId() const
1445{
1446 Q_D(const QFileInfo);
1447 return d->checkAttribute(uint(-2),
1448 QFileSystemMetaData::UserId,
1449 [d]() { return d->metaData.userId(); },
1450 [d]() { return d->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); });
1451}
1452
1453/*!
1454 Returns the group of the file. On Windows, on systems where files
1455 do not have groups, or if an error occurs, an empty string is
1456 returned.
1457
1458 This function can be time consuming under Unix (in the order of
1459 milliseconds).
1460
1461 \include qfileinfo.cpp info-about-target-not-symlink
1462
1463 \sa groupId(), owner(), ownerId()
1464*/
1465QString QFileInfo::group() const
1466{
1467 Q_D(const QFileInfo);
1468 if (d->isDefaultConstructed)
1469 return ""_L1;
1470 return d->getFileOwner(QAbstractFileEngine::OwnerGroup);
1471}
1472
1473/*!
1474 Returns the id of the group the file belongs to.
1475
1476 On Windows and on systems where files do not have groups this
1477 function always returns (uint) -2.
1478
1479 \include qfileinfo.cpp info-about-target-not-symlink
1480
1481 \sa group(), owner(), ownerId()
1482*/
1483uint QFileInfo::groupId() const
1484{
1485 Q_D(const QFileInfo);
1486 return d->checkAttribute(uint(-2),
1487 QFileSystemMetaData::GroupId,
1488 [d]() { return d->metaData.groupId(); },
1489 [d]() { return d->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); });
1490}
1491
1492/*!
1493 Tests for file permissions. The \a permissions argument can be
1494 several flags of type QFile::Permissions OR-ed together to check
1495 for permission combinations.
1496
1497 On systems where files do not have permissions this function
1498 always returns \c true.
1499
1500 \note The result might be inaccurate on Windows if the
1501 \l{NTFS permissions} check has not been enabled.
1502
1503 Example:
1504 \snippet code/src_corelib_io_qfileinfo.cpp 10
1505
1506 \include qfileinfo.cpp info-about-target-not-symlink
1507
1508 \sa isReadable(), isWritable(), isExecutable()
1509*/
1510bool QFileInfo::permission(QFile::Permissions permissions) const
1511{
1512 Q_D(const QFileInfo);
1513 // the QFileSystemMetaData::MetaDataFlag and QFile::Permissions overlap, so just cast.
1514 auto fseFlags = QFileSystemMetaData::MetaDataFlags::fromInt(permissions.toInt());
1515 auto feFlags = QAbstractFileEngine::FileFlags::fromInt(permissions.toInt());
1516 return d->checkAttribute<bool>(
1517 fseFlags,
1518 [=]() { return (d->metaData.permissions() & permissions) == permissions; },
1519 [=]() {
1520 return d->getFileFlags(feFlags) == uint(permissions.toInt());
1521 });
1522}
1523
1524/*!
1525 Returns the complete OR-ed together combination of
1526 QFile::Permissions for the file.
1527
1528 \note The result might be inaccurate on Windows if the
1529 \l{NTFS permissions} check has not been enabled.
1530
1531 \include qfileinfo.cpp info-about-target-not-symlink
1532*/
1533QFile::Permissions QFileInfo::permissions() const
1534{
1535 Q_D(const QFileInfo);
1536 return d->checkAttribute<QFile::Permissions>(
1537 QFileSystemMetaData::Permissions,
1538 [d]() { return d->metaData.permissions(); },
1539 [d]() {
1540 return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask);
1541 });
1542}
1543
1544
1545/*!
1546 Returns the file size in bytes. If the file does not exist or cannot be
1547 fetched, 0 is returned.
1548
1549 \include qfileinfo.cpp info-about-target-not-symlink
1550
1551 \sa exists()
1552*/
1553qint64 QFileInfo::size() const
1554{
1555 Q_D(const QFileInfo);
1556 return d->checkAttribute<qint64>(
1557 QFileSystemMetaData::SizeAttribute,
1558 [d]() { return d->metaData.size(); },
1559 [d]() {
1560 if (!d->getCachedFlag(QFileInfoPrivate::CachedSize)) {
1561 d->setCachedFlag(QFileInfoPrivate::CachedSize);
1562 d->fileSize = d->fileEngine->size();
1563 }
1564 return d->fileSize;
1565 });
1566}
1567
1568/*!
1569 \fn QDateTime QFileInfo::birthTime() const
1570
1571 Returns the date and time when the file was created (born), in local time.
1572
1573 If the file birth time is not available, this function returns an invalid QDateTime.
1574
1575 \include qfileinfo.cpp info-about-target-not-symlink
1576
1577 This function overloads QFileInfo::birthTime(const QTimeZone &tz), and
1578 returns the same as \c{birthTime(QTimeZone::LocalTime)}.
1579
1580 \since 5.10
1581 \sa lastModified(), lastRead(), metadataChangeTime(), fileTime()
1582*/
1583
1584/*!
1585 \fn QDateTime QFileInfo::birthTime(const QTimeZone &tz) const
1586
1587 Returns the date and time when the file was created (born).
1588
1589 \include qfileinfo.cpp file-times-in-time-zone
1590
1591 If the file birth time is not available, this function returns an invalid
1592 QDateTime.
1593
1594 \include qfileinfo.cpp info-about-target-not-symlink
1595
1596 \since 6.6
1597 \sa lastModified(const QTimeZone &), lastRead(const QTimeZone &),
1598 metadataChangeTime(const QTimeZone &),
1599 fileTime(QFileDevice::FileTime, const QTimeZone &)
1600*/
1601
1602/*!
1603 \fn QDateTime QFileInfo::metadataChangeTime() const
1604
1605 Returns the date and time when the file's metadata was last changed,
1606 in local time.
1607
1608 A metadata change occurs when the file is first created, but it also
1609 occurs whenever the user writes or sets inode information (for example,
1610 changing the file permissions).
1611
1612 \include qfileinfo.cpp info-about-target-not-symlink
1613
1614 This function overloads QFileInfo::metadataChangeTime(const QTimeZone &tz),
1615 and returns the same as \c{metadataChangeTime(QTimeZone::LocalTime)}.
1616
1617 \since 5.10
1618 \sa birthTime(), lastModified(), lastRead(), fileTime()
1619*/
1620
1621/*!
1622 \fn QDateTime QFileInfo::metadataChangeTime(const QTimeZone &tz) const
1623
1624 Returns the date and time when the file's metadata was last changed.
1625 A metadata change occurs when the file is first created, but it also
1626 occurs whenever the user writes or sets inode information (for example,
1627 changing the file permissions).
1628
1629 \include qfileinfo.cpp file-times-in-time-zone
1630
1631 \include qfileinfo.cpp info-about-target-not-symlink
1632
1633 \since 6.6
1634 \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &),
1635 lastRead(const QTimeZone &),
1636 fileTime(QFileDevice::FileTime time, const QTimeZone &)
1637*/
1638
1639/*!
1640 \fn QDateTime QFileInfo::lastModified() const
1641
1642 Returns the date and time when the file was last modified.
1643
1644 \include qfileinfo.cpp info-about-target-not-symlink
1645
1646 This function overloads \l{QFileInfo::lastModified(const QTimeZone &)},
1647 and returns the same as \c{lastModified(QTimeZone::LocalTime)}.
1648
1649 \sa birthTime(), lastRead(), metadataChangeTime(), fileTime()
1650*/
1651
1652/*!
1653 \fn QDateTime QFileInfo::lastModified(const QTimeZone &tz) const
1654
1655 Returns the date and time when the file was last modified.
1656
1657 \include qfileinfo.cpp file-times-in-time-zone
1658
1659 \include qfileinfo.cpp info-about-target-not-symlink
1660
1661 \since 6.6
1662 \sa birthTime(const QTimeZone &), lastRead(const QTimeZone &),
1663 metadataChangeTime(const QTimeZone &),
1664 fileTime(QFileDevice::FileTime, const QTimeZone &)
1665*/
1666
1667/*!
1668 \fn QDateTime QFileInfo::lastRead() const
1669
1670 Returns the date and time when the file was last read (accessed).
1671
1672 On platforms where this information is not available, returns the same
1673 time as lastModified().
1674
1675 \include qfileinfo.cpp info-about-target-not-symlink
1676
1677 This function overloads \l{QFileInfo::lastRead(const QTimeZone &)},
1678 and returns the same as \c{lastRead(QTimeZone::LocalTime)}.
1679
1680 \sa birthTime(), lastModified(), metadataChangeTime(), fileTime()
1681*/
1682
1683/*!
1684 \fn QDateTime QFileInfo::lastRead(const QTimeZone &tz) const
1685
1686 Returns the date and time when the file was last read (accessed).
1687
1688 \include qfileinfo.cpp file-times-in-time-zone
1689
1690 On platforms where this information is not available, returns the same
1691 time as lastModified().
1692
1693 \include qfileinfo.cpp info-about-target-not-symlink
1694
1695 \since 6.6
1696 \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &),
1697 metadataChangeTime(const QTimeZone &),
1698 fileTime(QFileDevice::FileTime, const QTimeZone &)
1699*/
1700
1701#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
1702/*!
1703 Returns the file time specified by \a time.
1704
1705 If the time cannot be determined, an invalid date time is returned.
1706
1707 \include qfileinfo.cpp info-about-target-not-symlink
1708
1709 This function overloads
1710 \l{QFileInfo::fileTime(QFileDevice::FileTime, const QTimeZone &)},
1711 and returns the same as \c{fileTime(time, QTimeZone::LocalTime)}.
1712
1713 \since 5.10
1714 \sa birthTime(), lastModified(), lastRead(), metadataChangeTime()
1715*/
1716QDateTime QFileInfo::fileTime(QFile::FileTime time) const {
1717 return fileTime(time, QTimeZone::LocalTime);
1718}
1719#endif
1720
1721/*!
1722 Returns the file time specified by \a time.
1723
1724//! [file-times-in-time-zone]
1725 The returned time is in the time zone specified by \a tz. For example,
1726 you can use QTimeZone::LocalTime or QTimeZone::UTC to get the time in
1727 the Local time zone or UTC, respectively. Since native file system API
1728 typically uses UTC, using QTimeZone::UTC is often faster, as it does not
1729 require any conversions.
1730//! [file-times-in-time-zone]
1731
1732 If the time cannot be determined, an invalid date time is returned.
1733
1734 \include qfileinfo.cpp info-about-target-not-symlink
1735
1736 \since 6.6
1737 \sa birthTime(const QTimeZone &), lastModified(const QTimeZone &),
1738 lastRead(const QTimeZone &), metadataChangeTime(const QTimeZone &),
1739 QDateTime::isValid()
1740*/
1741QDateTime QFileInfo::fileTime(QFile::FileTime time, const QTimeZone &tz) const
1742{
1743 Q_D(const QFileInfo);
1744 QFileSystemMetaData::MetaDataFlags flag;
1745 switch (time) {
1746 case QFile::FileAccessTime:
1747 flag = QFileSystemMetaData::AccessTime;
1748 break;
1749 case QFile::FileBirthTime:
1750 flag = QFileSystemMetaData::BirthTime;
1751 break;
1752 case QFile::FileMetadataChangeTime:
1753 flag = QFileSystemMetaData::MetadataChangeTime;
1754 break;
1755 case QFile::FileModificationTime:
1756 flag = QFileSystemMetaData::ModificationTime;
1757 break;
1758 }
1759
1760 auto fsLambda = [d, time]() { return d->metaData.fileTime(time); };
1761 auto engineLambda = [d, time]() { return d->getFileTime(time); };
1762 const auto dt =
1763 d->checkAttribute<QDateTime>(flag, std::move(fsLambda), std::move(engineLambda));
1764 return dt.toTimeZone(tz);
1765}
1766
1767/*!
1768 \internal
1769*/
1770QFileInfoPrivate* QFileInfo::d_func()
1771{
1772 return d_ptr.data();
1773}
1774
1775/*!
1776 Returns \c true if caching is enabled; otherwise returns \c false.
1777
1778 \sa setCaching(), refresh()
1779*/
1780bool QFileInfo::caching() const
1781{
1782 Q_D(const QFileInfo);
1783 return d->cache_enabled;
1784}
1785
1786/*!
1787 If \a enable is true, enables caching of file information. If \a
1788 enable is false caching is disabled.
1789
1790 When caching is enabled, QFileInfo reads the file information from
1791 the file system the first time it's needed, but generally not
1792 later.
1793
1794 Caching is enabled by default.
1795
1796 \sa refresh(), caching()
1797*/
1798void QFileInfo::setCaching(bool enable)
1799{
1800 Q_D(QFileInfo);
1801 d->cache_enabled = enable;
1802}
1803
1804/*!
1805 Reads all attributes from the file system.
1806 \since 6.0
1807
1808 This is useful when information about the file system is collected in a
1809 worker thread, and then passed to the UI in the form of caching QFileInfo
1810 instances.
1811
1812 \sa setCaching(), refresh()
1813*/
1814void QFileInfo::stat()
1815{
1816 Q_D(QFileInfo);
1817 QFileSystemEngine::fillMetaData(d->fileEntry, d->metaData, QFileSystemMetaData::AllMetaDataFlags);
1818}
1819
1820/*!
1821 \typedef QFileInfoList
1822 \relates QFileInfo
1823
1824 Synonym for QList<QFileInfo>.
1825*/
1826
1827#ifndef QT_NO_DEBUG_STREAM
1828QDebug operator<<(QDebug dbg, const QFileInfo &fi)
1829{
1830 QDebugStateSaver saver(dbg);
1831 dbg.nospace();
1832 dbg.noquote();
1833 dbg << "QFileInfo(" << QDir::toNativeSeparators(fi.filePath()) << ')';
1834 return dbg;
1835}
1836#endif
1837
1838/*!
1839 \fn QFileInfo::QFileInfo(const std::filesystem::path &file)
1840 \since 6.0
1841
1842 Constructs a new QFileInfo that gives information about the given
1843 \a file.
1844
1845 \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
1846*/
1847/*!
1848 \fn QFileInfo::QFileInfo(const QDir &dir, const std::filesystem::path &path)
1849 \since 6.0
1850
1851 Constructs a new QFileInfo that gives information about the file system
1852 entry at \a path that is relative to the directory \a dir.
1853
1854 \include qfileinfo.cpp preserve-relative-or-absolute
1855*/
1856/*!
1857 \fn void QFileInfo::setFile(const std::filesystem::path &path)
1858 \since 6.0
1859
1860 Sets the path of file system entry that this QFileInfo provides
1861 information about to \a path.
1862
1863 \include qfileinfo.cpp preserve-relative-path
1864*/
1865/*!
1866 \fn std::filesystem::path QFileInfo::filesystemFilePath() const
1867 \since 6.0
1868
1869 Returns filePath() as a \c{std::filesystem::path}.
1870 \sa filePath()
1871*/
1872/*!
1873 \fn std::filesystem::path QFileInfo::filesystemAbsoluteFilePath() const
1874 \since 6.0
1875
1876 Returns absoluteFilePath() as a \c{std::filesystem::path}.
1877 \sa absoluteFilePath()
1878*/
1879/*!
1880 \fn std::filesystem::path QFileInfo::filesystemCanonicalFilePath() const
1881 \since 6.0
1882
1883 Returns canonicalFilePath() as a \c{std::filesystem::path}.
1884 \sa canonicalFilePath()
1885*/
1886/*!
1887 \fn std::filesystem::path QFileInfo::filesystemPath() const
1888 \since 6.0
1889
1890 Returns path() as a \c{std::filesystem::path}.
1891 \sa path()
1892*/
1893/*!
1894 \fn std::filesystem::path QFileInfo::filesystemAbsolutePath() const
1895 \since 6.0
1896
1897 Returns absolutePath() as a \c{std::filesystem::path}.
1898 \sa absolutePath()
1899*/
1900/*!
1901 \fn std::filesystem::path QFileInfo::filesystemCanonicalPath() const
1902 \since 6.0
1903
1904 Returns canonicalPath() as a \c{std::filesystem::path}.
1905 \sa canonicalPath()
1906*/
1907/*!
1908 \fn std::filesystem::path QFileInfo::filesystemSymLinkTarget() const
1909 \since 6.0
1910
1911 Returns symLinkTarget() as a \c{std::filesystem::path}.
1912 \sa symLinkTarget()
1913*/
1914/*!
1915 \fn std::filesystem::path QFileInfo::filesystemReadSymLink() const
1916 \since 6.6
1917
1918 Returns readSymLink() as a \c{std::filesystem::path}.
1919 \sa readSymLink()
1920*/
1921/*!
1922 \fn std::filesystem::path QFileInfo::filesystemJunctionTarget() const
1923 \since 6.2
1924
1925 Returns junctionTarget() as a \c{std::filesystem::path}.
1926 \sa junctionTarget()
1927*/
1928/*!
1929 \macro QT_IMPLICIT_QFILEINFO_CONSTRUCTION
1930 \since 6.0
1931 \relates QFileInfo
1932
1933 Defining this macro makes most QFileInfo constructors implicit
1934 instead of explicit. Since construction of QFileInfo objects is
1935 expensive, one should avoid accidentally creating them, especially
1936 if cheaper alternatives exist. For instance:
1937
1938 \badcode
1939
1940 QDirIterator it(dir);
1941 while (it.hasNext()) {
1942 // Implicit conversion from QString (returned by it.next()):
1943 // may create unnecessary data structures and cause additional
1944 // accesses to the file system. Unless this macro is defined,
1945 // this line does not compile.
1946
1947 QFileInfo fi = it.next();
1948
1949 ~~~
1950 }
1951
1952 \endcode
1953
1954 Instead, use the right API:
1955
1956 \code
1957
1958 QDirIterator it(dir);
1959 while (it.hasNext()) {
1960 // Extract the QFileInfo from the iterator directly:
1961 QFileInfo fi = it.nextFileInfo();
1962
1963 ~~~
1964 }
1965
1966 \endcode
1967
1968 Construction from QString, QFile, and so on is always possible by
1969 using direct initialization instead of copy initialization:
1970
1971 \code
1972
1973 QFileInfo fi1 = some_string; // Does not compile unless this macro is defined
1974 QFileInfo fi2(some_string); // OK
1975 QFileInfo fi3{some_string}; // Possibly better, avoids the risk of the Most Vexing Parse
1976 auto fi4 = QFileInfo(some_string); // OK
1977
1978 \endcode
1979
1980 This macro is provided for compatibility reason. Its usage is not
1981 recommended in new code.
1982*/
1983
1984QT_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)