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
qstorageinfo.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2015 Ivan Komissarov <ABBAPOH@gmail.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6#include "qstorageinfo.h"
8
9#include "qdebug.h"
10
12
13Q_LOGGING_CATEGORY(lcStorageInfo, "qt.core.qstorageinfo", QtWarningMsg)
14
15QT_IMPL_METATYPE_EXTERN(QStorageInfo)
16QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QStorageInfoPrivate)
17
18/*!
19 \class QStorageInfo
20 \inmodule QtCore
21 \since 5.4
22 \brief Provides information about currently mounted storage and drives.
23
24 \ingroup io
25 \ingroup shared
26
27 \compares equality
28
29 Allows retrieving information about the volume's space, its mount point,
30 label, and filesystem name.
31
32 You can create an instance of QStorageInfo by passing the path to the
33 volume's mount point as a constructor parameter, or you can set it using
34 the setPath() method. The static mountedVolumes() method can be used to get the
35 list of all mounted filesystems.
36
37 QStorageInfo always caches the retrieved information, but you can call
38 refresh() to invalidate the cache.
39
40 The following example retrieves the most common information about the root
41 volume of the system, and prints information about it.
42
43 \snippet code/src_corelib_io_qstorageinfo.cpp 2
44*/
45
46QStorageInfo::QStorageInfo(QStorageInfoPrivate &dd)
47 : d(&dd)
48{
49}
50
51/*!
52 Constructs an empty QStorageInfo object.
53
54 Objects created with the default constructor will be invalid and therefore
55 not ready for use.
56
57 \sa setPath(), isReady(), isValid()
58*/
59QStorageInfo::QStorageInfo()
60 : d(new QStorageInfoPrivate)
61{
62}
63
64/*!
65 Constructs a new QStorageInfo object that gives information about the volume
66 mounted at \a path.
67
68 If you pass a directory or file, the QStorageInfo object will refer to the
69 volume where this directory or file is located.
70 You can check if the created object is correct using the isValid() method.
71
72 The following example shows how to get the volume on which the application is
73 located. It is recommended to always check that the volume is ready and valid.
74
75 \snippet code/src_corelib_io_qstorageinfo.cpp 0
76
77 \sa setPath()
78*/
79QStorageInfo::QStorageInfo(const QString &path)
80 : QStorageInfo()
81{
82 setPath(path);
83}
84
85/*!
86 Constructs a new QStorageInfo object that gives information about the volume
87 containing the \a dir folder.
88*/
89QStorageInfo::QStorageInfo(const QDir &dir)
90 : QStorageInfo(dir.absolutePath())
91{
92}
93
94/*!
95 Constructs a new QStorageInfo object that is a copy of the \a other QStorageInfo object.
96*/
97QStorageInfo::QStorageInfo(const QStorageInfo &other)
98 = default;
99
100/*!
101 \since 6.10
102 \fn QStorageInfo::QStorageInfo(QStorageInfo &&other)
103
104 Move-constructs a new QStorageInfo from \a other.
105
106 The moved-from object \a other is placed in a partially-formed state, in
107 which the only valid operations are destruction and assignment of a new
108 value.
109*/
110
111/*!
112 Destroys the QStorageInfo object and frees its resources.
113*/
114QStorageInfo::~QStorageInfo()
115 = default;
116
117/*!
118 Makes a copy of the QStorageInfo object \a other and assigns it to this QStorageInfo object.
119*/
120QStorageInfo &QStorageInfo::operator=(const QStorageInfo &other)
121 = default;
122
123/*!
124 \fn QStorageInfo &QStorageInfo::operator=(QStorageInfo &&other)
125
126 Move-assigns \a other to this QStorageInfo instance.
127
128 The moved-from object \a other is placed in a valid, but unspecified state.
129*/
130
131/*!
132 \fn void QStorageInfo::swap(QStorageInfo &other)
133 \memberswap{volume info}
134*/
135
136/*!
137 Sets this QStorageInfo object to the filesystem mounted where \a path is located.
138
139 \a path can either be a root path of the filesystem, a directory, or a file
140 within that filesystem.
141
142 \sa rootPath()
143*/
144void QStorageInfo::setPath(const QString &path)
145{
146 if (d->rootPath == path)
147 return;
148 d.detach();
149 d->rootPath = path;
150 d->doStat();
151}
152
153/*!
154 Returns the mount point of the filesystem this QStorageInfo object
155 represents.
156
157 On Windows, it returns the volume letter in case the volume is not mounted to
158 a directory.
159
160 Note that the value returned by rootPath() is the real mount point of a
161 volume, and may not be equal to the value passed to the constructor or setPath()
162 method. For example, if you have only the root volume in the system, and
163 pass '/directory' to setPath(), then this method will return '/'.
164
165 \sa setPath(), device()
166*/
167QString QStorageInfo::rootPath() const
168{
169 return d->rootPath;
170}
171
172/*!
173 Returns the size (in bytes) available for the current user. It returns
174 the total size available if the user is the root user or a system administrator.
175
176 This size can be less than or equal to the free size returned by
177 bytesFree() function.
178
179 Returns -1 if QStorageInfo object is not valid.
180
181 \sa bytesTotal(), bytesFree()
182*/
183qint64 QStorageInfo::bytesAvailable() const
184{
185 return d->bytesAvailable;
186}
187
188/*!
189 Returns the number of free bytes in a volume. Note that if there are
190 quotas on the filesystem, this value can be larger than the value
191 returned by bytesAvailable().
192
193 Returns -1 if QStorageInfo object is not valid.
194
195 \sa bytesTotal(), bytesAvailable()
196*/
197qint64 QStorageInfo::bytesFree() const
198{
199 return d->bytesFree;
200}
201
202/*!
203 Returns the total volume size in bytes.
204
205 Returns -1 if QStorageInfo object is not valid.
206
207 \sa bytesFree(), bytesAvailable()
208*/
209qint64 QStorageInfo::bytesTotal() const
210{
211 return d->bytesTotal;
212}
213
214/*!
215 \since 5.6
216 Returns the optimal transfer block size for this filesystem.
217
218 Returns -1 if QStorageInfo could not determine the size or if the QStorageInfo
219 object is not valid.
220 */
221int QStorageInfo::blockSize() const
222{
223 return d->blockSize;
224}
225
226/*!
227 Returns the type name of the filesystem.
228
229 This is a platform-dependent function, and filesystem names can vary
230 between different operating systems. For example, on Windows filesystems
231 they can be named \c NTFS, and on Linux they can be named \c ntfs-3g or \c fuseblk.
232
233 \sa name()
234*/
235QByteArray QStorageInfo::fileSystemType() const
236{
237 return d->fileSystemType;
238}
239
240/*!
241 Returns the device for this volume.
242
243 For example, on Unix filesystems (including \macos), this returns the
244 devpath like \c /dev/sda0 for local storages. On Windows, it returns the UNC
245 path starting with \c \\\\?\\ for local storages (in other words, the volume GUID).
246
247 \sa rootPath(), subvolume()
248*/
249QByteArray QStorageInfo::device() const
250{
251 return d->device;
252}
253
254/*!
255 \since 5.9
256 Returns the subvolume name for this volume.
257
258 Some filesystem types allow multiple subvolumes inside one device, which
259 may be mounted in different paths (e.g. 'bind' mounts on Unix, or Btrfs
260 filesystem subvolumes). If the subvolume could be detected, its name is
261 returned by this function. The format of the subvolume name is specific
262 to each filesystem type.
263
264 If this volume was not mounted from a subvolume of a larger filesystem or
265 if the subvolume could not be detected, this function returns an empty byte
266 array.
267
268 \sa device()
269*/
270QByteArray QStorageInfo::subvolume() const
271{
272 return d->subvolume;
273}
274
275/*!
276 Returns the human-readable name of a filesystem, usually called \c label.
277
278 Not all filesystems support this feature. In this case, the value returned by
279 this method could be empty. An empty string is returned if the file system
280 does not support labels, or if no label is set.
281
282 On Linux, retrieving the volume's label requires \c udev to be present in the
283 system.
284
285 \sa fileSystemType()
286*/
287QString QStorageInfo::name() const
288{
289 return d->name;
290}
291
292/*!
293 Returns the volume's name, if available, or the root path if not.
294*/
295QString QStorageInfo::displayName() const
296{
297 if (!d->name.isEmpty())
298 return d->name;
299 return d->rootPath;
300}
301
302/*!
303 \fn bool QStorageInfo::isRoot() const
304
305 Returns true if this QStorageInfo represents the system root volume; false
306 otherwise.
307
308 On Unix filesystems, the root volume is a volume mounted on \c /. On Windows,
309 the root volume is the volume where the OS is installed.
310
311 \sa root()
312*/
313
314/*!
315 Returns true if the current filesystem is protected from writing; false
316 otherwise.
317*/
318bool QStorageInfo::isReadOnly() const
319{
320 return d->readOnly;
321}
322
323/*!
324 Returns true if the current filesystem is ready to work; false otherwise. For
325 example, false is returned if the CD volume is not inserted.
326
327 Note that fileSystemType(), name(), bytesTotal(), bytesFree(), and
328 bytesAvailable() will return invalid data until the volume is ready.
329
330 \sa isValid()
331*/
332bool QStorageInfo::isReady() const
333{
334 return d->ready;
335}
336
337/*!
338 Returns true if the QStorageInfo specified by rootPath exists and is mounted
339 correctly.
340
341 \sa isReady()
342*/
343bool QStorageInfo::isValid() const
344{
345 return d->valid;
346}
347
348/*!
349 Resets QStorageInfo's internal cache.
350
351 QStorageInfo caches information about storage to speed up performance.
352 QStorageInfo retrieves information during object construction and/or when calling
353 the setPath() method. You have to manually reset the cache by calling this
354 function to update storage information.
355*/
356void QStorageInfo::refresh()
357{
358 d.detach();
359 d->doStat();
360}
361
362/*!
363 Returns the list of QStorageInfo objects that corresponds to the list of currently
364 mounted filesystems.
365
366 On Windows, this returns the drives visible in the \gui{My Computer} folder. On Unix
367 operating systems, it returns the list of all mounted filesystems (except for
368 pseudo filesystems).
369
370 Returns all currently mounted filesystems by default.
371
372 The example shows how to retrieve all available filesystems, skipping read-only ones.
373
374 \snippet code/src_corelib_io_qstorageinfo.cpp 1
375
376 \sa root()
377*/
378QList<QStorageInfo> QStorageInfo::mountedVolumes()
379{
380 return QStorageInfoPrivate::mountedVolumes();
381}
382
383Q_GLOBAL_STATIC(QStorageInfo, getRoot, QStorageInfoPrivate::root())
384
385/*!
386 Returns a QStorageInfo object that represents the system root volume.
387
388 On Unix systems this call returns the root ('/') volume; in Windows the volume where
389 the operating system is installed.
390
391 \sa isRoot()
392*/
393QStorageInfo QStorageInfo::root()
394{
395 return *getRoot();
396}
397
398/*!
399 \fn bool QStorageInfo::operator==(const QStorageInfo &lhs, const QStorageInfo &rhs)
400
401 Returns \c true if the QStorageInfo object \a lhs refers to the same drive or
402 volume as the QStorageInfo object \a rhs; otherwise it returns \c false.
403
404 Note that the result of comparing two invalid QStorageInfo objects is always
405 positive.
406*/
407
408/*!
409 \fn bool QStorageInfo::operator!=(const QStorageInfo &lhs, const QStorageInfo &rhs)
410
411 Returns \c true if the QStorageInfo object \a lhs refers to a different drive or
412 volume than the QStorageInfo object \a rhs; otherwise returns \c false.
413*/
414
415bool comparesEqual(const QStorageInfo &lhs, const QStorageInfo &rhs) noexcept
416{
417 if (lhs.d == rhs.d)
418 return true;
419 return lhs.d->device == rhs.d->device && lhs.d->rootPath == rhs.d->rootPath;
420}
421
422#ifndef QT_NO_DEBUG_STREAM
423QDebug operator<<(QDebug debug, const QStorageInfo &s)
424{
425 QDebugStateSaver saver(debug);
426 debug.nospace();
427 debug.noquote();
428 debug << "QStorageInfo(";
429 if (s.isValid()) {
430 const QStorageInfoPrivate *d = s.d.constData();
431 debug << '"' << d->rootPath << '"';
432 if (!d->fileSystemType.isEmpty())
433 debug << ", type=" << d->fileSystemType;
434 if (!d->name.isEmpty())
435 debug << ", name=\"" << d->name << '"';
436 if (!d->device.isEmpty())
437 debug << ", device=\"" << d->device << '"';
438 if (!d->subvolume.isEmpty())
439 debug << ", subvolume=\"" << d->subvolume << '"';
440 if (d->readOnly)
441 debug << " [read only]";
442 debug << (d->ready ? " [ready]" : " [not ready]");
443 if (d->bytesTotal > 0) {
444 debug << ", bytesTotal=" << d->bytesTotal << ", bytesFree=" << d->bytesFree
445 << ", bytesAvailable=" << d->bytesAvailable;
446 }
447 } else {
448 debug << "invalid";
449 }
450 debug << ')';
451 return debug;
452}
453#endif // !QT_NO_DEBUG_STREAM
454
455QT_END_NAMESPACE
Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames, { { Qt::DisplayRole, "display" }, { Qt::DecorationRole, "decoration" }, { Qt::EditRole, "edit" }, { Qt::ToolTipRole, "toolTip" }, { Qt::StatusTipRole, "statusTip" }, { Qt::WhatsThisRole, "whatsThis" }, }) const QHash< int
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)