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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/corelib/io/qfileinfo.cpp