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
124 Swaps this volume info with \a other. This function is very fast and
125 never fails.
126*/
127
128/*!
129 Sets this QStorageInfo object to the filesystem mounted where \a path is located.
130
131 \a path can either be a root path of the filesystem, a directory, or a file
132 within that filesystem.
133
134 \sa rootPath()
135*/
136void QStorageInfo::setPath(const QString &path)
137{
138 if (d->rootPath == path)
139 return;
140 d.detach();
141 d->rootPath = path;
142 d->doStat();
143}
144
145/*!
146 Returns the mount point of the filesystem this QStorageInfo object
147 represents.
148
149 On Windows, it returns the volume letter in case the volume is not mounted to
150 a directory.
151
152 Note that the value returned by rootPath() is the real mount point of a
153 volume, and may not be equal to the value passed to the constructor or setPath()
154 method. For example, if you have only the root volume in the system, and
155 pass '/directory' to setPath(), then this method will return '/'.
156
157 \sa setPath(), device()
158*/
159QString QStorageInfo::rootPath() const
160{
161 return d->rootPath;
162}
163
164/*!
165 Returns the size (in bytes) available for the current user. It returns
166 the total size available if the user is the root user or a system administrator.
167
168 This size can be less than or equal to the free size returned by
169 bytesFree() function.
170
171 Returns -1 if QStorageInfo object is not valid.
172
173 \sa bytesTotal(), bytesFree()
174*/
175qint64 QStorageInfo::bytesAvailable() const
176{
177 return d->bytesAvailable;
178}
179
180/*!
181 Returns the number of free bytes in a volume. Note that if there are
182 quotas on the filesystem, this value can be larger than the value
183 returned by bytesAvailable().
184
185 Returns -1 if QStorageInfo object is not valid.
186
187 \sa bytesTotal(), bytesAvailable()
188*/
189qint64 QStorageInfo::bytesFree() const
190{
191 return d->bytesFree;
192}
193
194/*!
195 Returns the total volume size in bytes.
196
197 Returns -1 if QStorageInfo object is not valid.
198
199 \sa bytesFree(), bytesAvailable()
200*/
201qint64 QStorageInfo::bytesTotal() const
202{
203 return d->bytesTotal;
204}
205
206/*!
207 \since 5.6
208 Returns the optimal transfer block size for this filesystem.
209
210 Returns -1 if QStorageInfo could not determine the size or if the QStorageInfo
211 object is not valid.
212 */
213int QStorageInfo::blockSize() const
214{
215 return d->blockSize;
216}
217
218/*!
219 Returns the type name of the filesystem.
220
221 This is a platform-dependent function, and filesystem names can vary
222 between different operating systems. For example, on Windows filesystems
223 they can be named \c NTFS, and on Linux they can be named \c ntfs-3g or \c fuseblk.
224
225 \sa name()
226*/
227QByteArray QStorageInfo::fileSystemType() const
228{
229 return d->fileSystemType;
230}
231
232/*!
233 Returns the device for this volume.
234
235 For example, on Unix filesystems (including \macos), this returns the
236 devpath like \c /dev/sda0 for local storages. On Windows, it returns the UNC
237 path starting with \c \\\\?\\ for local storages (in other words, the volume GUID).
238
239 \sa rootPath(), subvolume()
240*/
241QByteArray QStorageInfo::device() const
242{
243 return d->device;
244}
245
246/*!
247 \since 5.9
248 Returns the subvolume name for this volume.
249
250 Some filesystem types allow multiple subvolumes inside one device, which
251 may be mounted in different paths (e.g. 'bind' mounts on Unix, or Btrfs
252 filesystem subvolumes). If the subvolume could be detected, its name is
253 returned by this function. The format of the subvolume name is specific
254 to each filesystem type.
255
256 If this volume was not mounted from a subvolume of a larger filesystem or
257 if the subvolume could not be detected, this function returns an empty byte
258 array.
259
260 \sa device()
261*/
262QByteArray QStorageInfo::subvolume() const
263{
264 return d->subvolume;
265}
266
267/*!
268 Returns the human-readable name of a filesystem, usually called \c label.
269
270 Not all filesystems support this feature. In this case, the value returned by
271 this method could be empty. An empty string is returned if the file system
272 does not support labels, or if no label is set.
273
274 On Linux, retrieving the volume's label requires \c udev to be present in the
275 system.
276
277 \sa fileSystemType()
278*/
279QString QStorageInfo::name() const
280{
281 return d->name;
282}
283
284/*!
285 Returns the volume's name, if available, or the root path if not.
286*/
287QString QStorageInfo::displayName() const
288{
289 if (!d->name.isEmpty())
290 return d->name;
291 return d->rootPath;
292}
293
294/*!
295 \fn bool QStorageInfo::isRoot() const
296
297 Returns true if this QStorageInfo represents the system root volume; false
298 otherwise.
299
300 On Unix filesystems, the root volume is a volume mounted on \c /. On Windows,
301 the root volume is the volume where the OS is installed.
302
303 \sa root()
304*/
305
306/*!
307 Returns true if the current filesystem is protected from writing; false
308 otherwise.
309*/
310bool QStorageInfo::isReadOnly() const
311{
312 return d->readOnly;
313}
314
315/*!
316 Returns true if the current filesystem is ready to work; false otherwise. For
317 example, false is returned if the CD volume is not inserted.
318
319 Note that fileSystemType(), name(), bytesTotal(), bytesFree(), and
320 bytesAvailable() will return invalid data until the volume is ready.
321
322 \sa isValid()
323*/
324bool QStorageInfo::isReady() const
325{
326 return d->ready;
327}
328
329/*!
330 Returns true if the QStorageInfo specified by rootPath exists and is mounted
331 correctly.
332
333 \sa isReady()
334*/
335bool QStorageInfo::isValid() const
336{
337 return d->valid;
338}
339
340/*!
341 Resets QStorageInfo's internal cache.
342
343 QStorageInfo caches information about storage to speed up performance.
344 QStorageInfo retrieves information during object construction and/or when calling
345 the setPath() method. You have to manually reset the cache by calling this
346 function to update storage information.
347*/
348void QStorageInfo::refresh()
349{
350 d.detach();
351 d->doStat();
352}
353
354/*!
355 Returns the list of QStorageInfo objects that corresponds to the list of currently
356 mounted filesystems.
357
358 On Windows, this returns the drives visible in the \gui{My Computer} folder. On Unix
359 operating systems, it returns the list of all mounted filesystems (except for
360 pseudo filesystems).
361
362 Returns all currently mounted filesystems by default.
363
364 The example shows how to retrieve all available filesystems, skipping read-only ones.
365
366 \snippet code/src_corelib_io_qstorageinfo.cpp 1
367
368 \sa root()
369*/
370QList<QStorageInfo> QStorageInfo::mountedVolumes()
371{
372 return QStorageInfoPrivate::mountedVolumes();
373}
374
375Q_GLOBAL_STATIC(QStorageInfo, getRoot, QStorageInfoPrivate::root())
376
377/*!
378 Returns a QStorageInfo object that represents the system root volume.
379
380 On Unix systems this call returns the root ('/') volume; in Windows the volume where
381 the operating system is installed.
382
383 \sa isRoot()
384*/
385QStorageInfo QStorageInfo::root()
386{
387 return *getRoot();
388}
389
390/*!
391 \fn bool QStorageInfo::operator==(const QStorageInfo &lhs, const QStorageInfo &rhs)
392
393 Returns \c true if the QStorageInfo object \a lhs refers to the same drive or
394 volume as the QStorageInfo object \a rhs; otherwise it returns \c false.
395
396 Note that the result of comparing two invalid QStorageInfo objects is always
397 positive.
398*/
399
400/*!
401 \fn bool QStorageInfo::operator!=(const QStorageInfo &lhs, const QStorageInfo &rhs)
402
403 Returns \c true if the QStorageInfo object \a lhs refers to a different drive or
404 volume than the QStorageInfo object \a rhs; otherwise returns \c false.
405*/
406
407bool comparesEqual(const QStorageInfo &lhs, const QStorageInfo &rhs) noexcept
408{
409 if (lhs.d == rhs.d)
410 return true;
411 return lhs.d->device == rhs.d->device && lhs.d->rootPath == rhs.d->rootPath;
412}
413
414#ifndef QT_NO_DEBUG_STREAM
415QDebug operator<<(QDebug debug, const QStorageInfo &s)
416{
417 QDebugStateSaver saver(debug);
418 debug.nospace();
419 debug.noquote();
420 debug << "QStorageInfo(";
421 if (s.isValid()) {
422 const QStorageInfoPrivate *d = s.d.constData();
423 debug << '"' << d->rootPath << '"';
424 if (!d->fileSystemType.isEmpty())
425 debug << ", type=" << d->fileSystemType;
426 if (!d->name.isEmpty())
427 debug << ", name=\"" << d->name << '"';
428 if (!d->device.isEmpty())
429 debug << ", device=\"" << d->device << '"';
430 if (!d->subvolume.isEmpty())
431 debug << ", subvolume=\"" << d->subvolume << '"';
432 if (d->readOnly)
433 debug << " [read only]";
434 debug << (d->ready ? " [ready]" : " [not ready]");
435 if (d->bytesTotal > 0) {
436 debug << ", bytesTotal=" << d->bytesTotal << ", bytesFree=" << d->bytesFree
437 << ", bytesAvailable=" << d->bytesAvailable;
438 }
439 } else {
440 debug << "invalid";
441 }
442 debug << ')';
443 return debug;
444}
445#endif // !QT_NO_DEBUG_STREAM
446
447QT_END_NAMESPACE
448

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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