source: vendor/trolltech/current/src/tools/qfileinfo.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 17.6 KB
Line 
1/****************************************************************************
2** $Id: qfileinfo.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QFileInfo class
5**
6** Created : 950628
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qplatformdefs.h"
39
40#include "qfileinfo.h"
41#include "qdatetime.h"
42#include "qdir.h"
43#include "qfiledefs_p.h"
44#include "qdeepcopy.h"
45#if defined(QT_LARGEFILE_SUPPORT) && !defined(QT_ABI_QT4)
46#include <limits.h>
47#endif
48
49
50extern bool qt_file_access( const QString& fn, int t );
51
52/*!
53 \class QFileInfo
54 \reentrant
55 \brief The QFileInfo class provides system-independent file information.
56
57 \ingroup io
58
59 QFileInfo provides information about a file's name and position
60 (path) in the file system, its access rights and whether it is a
61 directory or symbolic link, etc. The file's size and last
62 modified/read times are also available.
63
64 A QFileInfo can point to a file with either a relative or an
65 absolute file path. Absolute file paths begin with the directory
66 separator "/" (or with a drive specification on Windows). Relative
67 file names begin with a directory name or a file name and specify
68 a path relative to the current working directory. An example of an
69 absolute path is the string "/tmp/quartz". A relative path might
70 look like "src/fatlib". You can use the function isRelative() to
71 check whether a QFileInfo is using a relative or an absolute file
72 path. You can call the function convertToAbs() to convert a
73 relative QFileInfo's path to an absolute path.
74
75 The file that the QFileInfo works on is set in the constructor or
76 later with setFile(). Use exists() to see if the file exists and
77 size() to get its size.
78
79 To speed up performance, QFileInfo caches information about the
80 file. Because files can be changed by other users or programs, or
81 even by other parts of the same program, there is a function that
82 refreshes the file information: refresh(). If you want to switch
83 off a QFileInfo's caching and force it to access the file system
84 every time you request information from it call setCaching(FALSE).
85
86 The file's type is obtained with isFile(), isDir() and
87 isSymLink(). The readLink() function provides the name of the file
88 the symlink points to.
89
90 Elements of the file's name can be extracted with dirPath() and
91 fileName(). The fileName()'s parts can be extracted with
92 baseName() and extension().
93
94 The file's dates are returned by created(), lastModified() and
95 lastRead(). Information about the file's access permissions is
96 obtained with isReadable(), isWritable() and isExecutable(). The
97 file's ownership is available from owner(), ownerId(), group() and
98 groupId(). You can examine a file's permissions and ownership in a
99 single statement using the permission() function.
100
101 If you need to read and traverse directories, see the QDir class.
102*/
103
104/*!
105 \enum QFileInfo::PermissionSpec
106
107 This enum is used by the permission() function to report the
108 permissions and ownership of a file. The values may be OR-ed
109 together to test multiple permissions and ownership values.
110
111 \value ReadOwner The file is readable by the owner of the file.
112 \value WriteOwner The file is writable by the owner of the file.
113 \value ExeOwner The file is executable by the owner of the file.
114 \value ReadUser The file is readable by the user.
115 \value WriteUser The file is writable by the user.
116 \value ExeUser The file is executable by the user.
117 \value ReadGroup The file is readable by the group.
118 \value WriteGroup The file is writable by the group.
119 \value ExeGroup The file is executable by the group.
120 \value ReadOther The file is readable by anyone.
121 \value WriteOther The file is writable by anyone.
122 \value ExeOther The file is executable by anyone.
123
124 \warning The semantics of \c ReadUser, \c WriteUser and \c ExeUser are
125 unfortunately not platform independent: on Unix, the rights of the owner of
126 the file are returned and on Windows the rights of the current user are
127 returned. This behavior might change in a future Qt version. If you want to
128 find the rights of the owner of the file, you should use the flags \c
129 ReadOwner, \c WriteOwner and \c ExeOwner. If you want to find out the
130 rights of the current user, you should use isReadable(), isWritable() and
131 isExecutable().
132*/
133
134
135/*!
136 Constructs a new empty QFileInfo.
137*/
138
139QFileInfo::QFileInfo()
140{
141 fic = 0;
142 cache = TRUE;
143#if defined(Q_OS_UNIX)
144 symLink = FALSE;
145#endif
146}
147
148/*!
149 Constructs a new QFileInfo that gives information about the given
150 file. The \a file can also include an absolute or relative path.
151
152 \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
153*/
154
155QFileInfo::QFileInfo( const QString &file )
156{
157 fn = file;
158 slashify( fn );
159 fic = 0;
160 cache = TRUE;
161#if defined(Q_OS_UNIX)
162 symLink = FALSE;
163#endif
164}
165
166/*!
167 Constructs a new QFileInfo that gives information about file \a
168 file.
169
170 If the \a file has a relative path, the QFileInfo will also have a
171 relative path.
172
173 \sa isRelative()
174*/
175
176QFileInfo::QFileInfo( const QFile &file )
177{
178 fn = file.name();
179 slashify( fn );
180 fic = 0;
181 cache = TRUE;
182#if defined(Q_OS_UNIX)
183 symLink = FALSE;
184#endif
185}
186
187/*!
188 Constructs a new QFileInfo that gives information about the file
189 called \a fileName in the directory \a d.
190
191 If \a d has a relative path, the QFileInfo will also have a
192 relative path.
193
194 \sa isRelative()
195*/
196#ifndef QT_NO_DIR
197QFileInfo::QFileInfo( const QDir &d, const QString &fileName )
198{
199 fn = d.filePath( fileName );
200 slashify( fn );
201 fic = 0;
202 cache = TRUE;
203#if defined(Q_OS_UNIX)
204 symLink = FALSE;
205#endif
206}
207#endif
208/*!
209 Constructs a new QFileInfo that is a copy of \a fi.
210*/
211
212QFileInfo::QFileInfo( const QFileInfo &fi )
213{
214 fn = fi.fn;
215 if ( fi.fic ) {
216 fic = new QFileInfoCache;
217 *fic = *fi.fic;
218 } else {
219 fic = 0;
220 }
221 cache = fi.cache;
222#if defined(Q_OS_UNIX)
223 symLink = fi.symLink;
224#endif
225}
226
227/*!
228 Destroys the QFileInfo and frees its resources.
229*/
230
231QFileInfo::~QFileInfo()
232{
233 delete fic;
234}
235
236
237/*!
238 Makes a copy of \a fi and assigns it to this QFileInfo.
239*/
240
241QFileInfo &QFileInfo::operator=( const QFileInfo &fi )
242{
243 fn = fi.fn;
244 if ( !fi.fic ) {
245 delete fic;
246 fic = 0;
247 } else {
248 if ( !fic ) {
249 fic = new QFileInfoCache;
250 Q_CHECK_PTR( fic );
251 }
252 *fic = *fi.fic;
253 }
254 cache = fi.cache;
255#if defined(Q_OS_UNIX)
256 symLink = fi.symLink;
257#endif
258 return *this;
259}
260
261
262/*!
263 Sets the file that the QFileInfo provides information about to \a
264 file.
265
266 The \a file can also include an absolute or relative file path.
267 Absolute paths begin with the directory separator (e.g. "/" under
268 Unix) or a drive specification (under Windows). Relative file
269 names begin with a directory name or a file name and specify a
270 path relative to the current directory.
271
272 Example:
273 \code
274 QString absolute = "/local/bin";
275 QString relative = "local/bin";
276 QFileInfo absFile( absolute );
277 QFileInfo relFile( relative );
278
279 QDir::setCurrent( QDir::rootDirPath() );
280 // absFile and relFile now point to the same file
281
282 QDir::setCurrent( "/tmp" );
283 // absFile now points to "/local/bin",
284 // while relFile points to "/tmp/local/bin"
285 \endcode
286
287 \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
288*/
289
290void QFileInfo::setFile( const QString &file )
291{
292 fn = file;
293 slashify( fn );
294 delete fic;
295 fic = 0;
296}
297
298/*!
299 \overload
300
301 Sets the file that the QFileInfo provides information about to \a
302 file.
303
304 If \a file includes a relative path, the QFileInfo will also have
305 a relative path.
306
307 \sa isRelative()
308*/
309
310void QFileInfo::setFile( const QFile &file )
311{
312 fn = file.name();
313 slashify( fn );
314 delete fic;
315 fic = 0;
316}
317
318/*!
319 \overload
320
321 Sets the file that the QFileInfo provides information about to \a
322 fileName in directory \a d.
323
324 If \a fileName includes a relative path, the QFileInfo will also
325 have a relative path.
326
327 \sa isRelative()
328*/
329#ifndef QT_NO_DIR
330void QFileInfo::setFile( const QDir &d, const QString &fileName )
331{
332 fn = d.filePath( fileName );
333 slashify( fn );
334 delete fic;
335 fic = 0;
336}
337#endif
338
339/*!
340 Returns TRUE if the file exists; otherwise returns FALSE.
341*/
342
343bool QFileInfo::exists() const
344{
345 return qt_file_access( fn, F_OK );
346}
347
348/*!
349 Refreshes the information about the file, i.e. reads in information
350 from the file system the next time a cached property is fetched.
351
352 \sa setCaching()
353*/
354
355void QFileInfo::refresh() const
356{
357 QFileInfo *that = (QFileInfo*)this; // Mutable function
358 delete that->fic;
359 that->fic = 0;
360}
361
362/*!
363 \fn bool QFileInfo::caching() const
364
365 Returns TRUE if caching is enabled; otherwise returns FALSE.
366
367 \sa setCaching(), refresh()
368*/
369
370/*!
371 If \a enable is TRUE, enables caching of file information. If \a
372 enable is FALSE caching is disabled.
373
374 When caching is enabled, QFileInfo reads the file information from
375 the file system the first time it's needed, but generally not
376 later.
377
378 Caching is enabled by default.
379
380 \sa refresh(), caching()
381*/
382
383void QFileInfo::setCaching( bool enable )
384{
385 if ( cache == enable )
386 return;
387 cache = enable;
388 if ( cache ) {
389 delete fic;
390 fic = 0;
391 }
392}
393
394
395/*!
396 Returns the file name, including the path (which may be absolute
397 or relative).
398
399 \sa isRelative(), absFilePath()
400*/
401
402QString QFileInfo::filePath() const
403{
404 return fn;
405}
406
407/*!
408 Returns the base name of the file.
409
410 If \a complete is FALSE (the default) the base name consists of
411 all characters in the file name up to (but not including) the \e
412 first '.' character.
413
414 If \a complete is TRUE the base name consists of all characters in
415 the file up to (but not including) the \e last '.' character.
416
417 The path is not included in either case.
418
419 Example:
420 \code
421 QFileInfo fi( "/tmp/archive.tar.gz" );
422 QString base = fi.baseName(); // base = "archive"
423 base = fi.baseName( TRUE ); // base = "archive.tar"
424 \endcode
425
426 \sa fileName(), extension()
427*/
428
429QString QFileInfo::baseName( bool complete ) const
430{
431 QString tmp = fileName();
432 int pos = complete ? tmp.findRev( '.' ) : tmp.find( '.' );
433 if ( pos == -1 )
434 return tmp;
435 else
436 return tmp.left( pos );
437}
438
439/*!
440 Returns the file's extension name.
441
442 If \a complete is TRUE (the default), extension() returns the
443 string of all characters in the file name after (but not
444 including) the first '.' character.
445
446 If \a complete is FALSE, extension() returns the string of all
447 characters in the file name after (but not including) the last '.'
448 character.
449
450 Example:
451 \code
452 QFileInfo fi( "/tmp/archive.tar.gz" );
453 QString ext = fi.extension(); // ext = "tar.gz"
454 ext = fi.extension( FALSE ); // ext = "gz"
455 \endcode
456
457 \sa fileName(), baseName()
458*/
459
460QString QFileInfo::extension( bool complete ) const
461{
462 QString s = fileName();
463 int pos = complete ? s.find( '.' ) : s.findRev( '.' );
464 if ( pos < 0 )
465 return QString::fromLatin1( "" );
466 else
467 return s.right( s.length() - pos - 1 );
468}
469
470/*!
471 Returns the file's path as a QDir object.
472
473 If the QFileInfo is relative and \a absPath is FALSE, the QDir
474 will be relative; otherwise it will be absolute.
475
476 \sa dirPath(), filePath(), fileName(), isRelative()
477*/
478#ifndef QT_NO_DIR
479QDir QFileInfo::dir( bool absPath ) const
480{
481 return QDir( dirPath(absPath) );
482}
483#endif
484
485
486/*!
487 Returns TRUE if the file is readable; otherwise returns FALSE.
488
489 \sa isWritable(), isExecutable(), permission()
490*/
491
492bool QFileInfo::isReadable() const
493{
494#ifdef Q_WS_WIN
495 return qt_file_access( fn, R_OK ) && permission( ReadUser );
496#else
497 return qt_file_access( fn, R_OK );
498#endif
499}
500
501/*!
502 Returns TRUE if the file is writable; otherwise returns FALSE.
503
504 \sa isReadable(), isExecutable(), permission()
505*/
506
507bool QFileInfo::isWritable() const
508{
509#ifdef Q_WS_WIN
510 return qt_file_access( fn, W_OK ) && permission( WriteUser );
511#else
512 return qt_file_access( fn, W_OK );
513#endif
514}
515
516/*!
517 Returns TRUE if the file is executable; otherwise returns FALSE.
518
519 \sa isReadable(), isWritable(), permission()
520*/
521
522bool QFileInfo::isExecutable() const
523{
524#ifdef Q_WS_WIN
525 return qt_file_access( fn, X_OK ) && permission( ExeUser );
526#else
527 return qt_file_access( fn, X_OK );
528#endif
529}
530
531#ifndef Q_WS_WIN
532bool QFileInfo::isHidden() const
533{
534 return fileName()[ 0 ] == QChar( '.' );
535}
536#endif
537
538/*!
539 Returns TRUE if the file path name is relative. Returns FALSE if
540 the path is absolute (e.g. under Unix a path is absolute if it
541 begins with a "/").
542*/
543#ifndef QT_NO_DIR
544bool QFileInfo::isRelative() const
545{
546 return QDir::isRelativePath( fn );
547}
548
549/*!
550 Converts the file's path to an absolute path.
551
552 If it is already absolute, nothing is done.
553
554 \sa filePath(), isRelative()
555*/
556
557bool QFileInfo::convertToAbs()
558{
559 if ( isRelative() )
560 fn = absFilePath();
561 return QDir::isRelativePath( fn );
562}
563#endif
564
565/*!
566 Returns the file size in bytes, or 0 if the file does not exist or
567 if the size is 0 or if the size cannot be fetched.
568*/
569#if defined(QT_ABI_QT4)
570QIODevice::Offset QFileInfo::size() const
571#else
572uint QFileInfo::size() const
573#endif
574{
575 if ( !fic || !cache )
576 doStat();
577 if ( fic )
578#if defined(QT_ABI_QT4)
579 return (QIODevice::Offset)fic->st.st_size;
580#elif defined(QT_LARGEFILE_SUPPORT)
581 return (uint)fic->st.st_size > UINT_MAX ? UINT_MAX : (uint)fic->st.st_size;
582#else
583 return (uint)fic->st.st_size;
584#endif
585 else
586 return 0;
587}
588
589/*!
590 Returns the date and time when the file was created.
591
592 On platforms where this information is not available, returns the
593 same as lastModified().
594
595 \sa created() lastModified() lastRead()
596*/
597
598QDateTime QFileInfo::created() const
599{
600 QDateTime dt;
601 if ( !fic || !cache )
602 doStat();
603 if ( fic && fic->st.st_ctime != 0 ) {
604 dt.setTime_t( fic->st.st_ctime );
605 return dt;
606 } else {
607 return lastModified();
608 }
609}
610
611/*!
612 Returns the date and time when the file was last modified.
613
614 \sa created() lastModified() lastRead()
615*/
616
617QDateTime QFileInfo::lastModified() const
618{
619 QDateTime dt;
620 if ( !fic || !cache )
621 doStat();
622 if ( fic )
623 dt.setTime_t( fic->st.st_mtime );
624 return dt;
625}
626
627/*!
628 Returns the date and time when the file was last read (accessed).
629
630 On platforms where this information is not available, returns the
631 same as lastModified().
632
633 \sa created() lastModified() lastRead()
634*/
635
636QDateTime QFileInfo::lastRead() const
637{
638 QDateTime dt;
639 if ( !fic || !cache )
640 doStat();
641 if ( fic && fic->st.st_atime != 0 ) {
642 dt.setTime_t( fic->st.st_atime );
643 return dt;
644 } else {
645 return lastModified();
646 }
647}
648
649#ifndef QT_NO_DIR
650
651/*!
652 Returns the absolute path including the file name.
653
654 The absolute path name consists of the full path and the file
655 name. On Unix this will always begin with the root, '/',
656 directory. On Windows this will always begin 'D:/' where D is a
657 drive letter, except for network shares that are not mapped to a
658 drive letter, in which case the path will begin '//sharename/'.
659
660 This function returns the same as filePath(), unless isRelative()
661 is TRUE.
662
663 If the QFileInfo is empty it returns QDir::currentDirPath().
664
665 This function can be time consuming under Unix (in the order of
666 milliseconds).
667
668 \sa isRelative(), filePath()
669*/
670QString QFileInfo::absFilePath() const
671{
672 QString tmp;
673 if ( QDir::isRelativePath(fn)
674#if defined(Q_OS_WIN32)
675 && fn[1] != ':'
676#endif
677 ) {
678 tmp = QDir::currentDirPath();
679 tmp += '/';
680 }
681 tmp += fn;
682 makeAbs( tmp );
683 return QDir::cleanDirPath( tmp );
684}
685
686/*! \internal
687 Detaches all internal data.
688*/
689void QFileInfo::detach()
690{
691 fn = QDeepCopy<QString>( fn );
692 if ( fic ) {
693 QFileInfoCache *cur = fic;
694 fic = new QFileInfoCache;
695 *fic = *cur;
696 delete cur;
697 }
698}
699
700#endif
Note: See TracBrowser for help on using the repository browser.