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