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

Provided by KDAB

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

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