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