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