source: trunk/src/tools/qfileinfo.cpp@ 123

Last change on this file since 123 was 8, checked in by dmik, 20 years ago

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

  • Property svn:keywords set to Id
File size: 17.8 KB
Line 
1/****************************************************************************
2** $Id: qfileinfo.cpp 8 2005-11-16 19:36:46Z 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 and OS/2). 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 @@TODO: describe OS/2 semantics regarding permissions.
134*/
135
136
137/*!
138 Constructs a new empty QFileInfo.
139*/
140
141QFileInfo::QFileInfo()
142{
143 fic = 0;
144 cache = TRUE;
145#if defined(Q_OS_UNIX)
146 symLink = FALSE;
147#endif
148}
149
150/*!
151 Constructs a new QFileInfo that gives information about the given
152 file. The \a file can also include an absolute or relative path.
153
154 \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
155*/
156
157QFileInfo::QFileInfo( const QString &file )
158{
159 fn = file;
160 slashify( fn );
161 fic = 0;
162 cache = TRUE;
163#if defined(Q_OS_UNIX)
164 symLink = FALSE;
165#endif
166}
167
168/*!
169 Constructs a new QFileInfo that gives information about file \a
170 file.
171
172 If the \a file has a relative path, the QFileInfo will also have a
173 relative path.
174
175 \sa isRelative()
176*/
177
178QFileInfo::QFileInfo( const QFile &file )
179{
180 fn = file.name();
181 slashify( fn );
182 fic = 0;
183 cache = TRUE;
184#if defined(Q_OS_UNIX)
185 symLink = FALSE;
186#endif
187}
188
189/*!
190 Constructs a new QFileInfo that gives information about the file
191 called \a fileName in the directory \a d.
192
193 If \a d has a relative path, the QFileInfo will also have a
194 relative path.
195
196 \sa isRelative()
197*/
198#ifndef QT_NO_DIR
199QFileInfo::QFileInfo( const QDir &d, const QString &fileName )
200{
201 fn = d.filePath( fileName );
202 slashify( fn );
203 fic = 0;
204 cache = TRUE;
205#if defined(Q_OS_UNIX)
206 symLink = FALSE;
207#endif
208}
209#endif
210/*!
211 Constructs a new QFileInfo that is a copy of \a fi.
212*/
213
214QFileInfo::QFileInfo( const QFileInfo &fi )
215{
216 fn = fi.fn;
217 if ( fi.fic ) {
218 fic = new QFileInfoCache;
219 *fic = *fi.fic;
220 } else {
221 fic = 0;
222 }
223 cache = fi.cache;
224#if defined(Q_OS_UNIX)
225 symLink = fi.symLink;
226#endif
227}
228
229/*!
230 Destroys the QFileInfo and frees its resources.
231*/
232
233QFileInfo::~QFileInfo()
234{
235 delete fic;
236}
237
238
239/*!
240 Makes a copy of \a fi and assigns it to this QFileInfo.
241*/
242
243QFileInfo &QFileInfo::operator=( const QFileInfo &fi )
244{
245 fn = fi.fn;
246 if ( !fi.fic ) {
247 delete fic;
248 fic = 0;
249 } else {
250 if ( !fic ) {
251 fic = new QFileInfoCache;
252 Q_CHECK_PTR( fic );
253 }
254 *fic = *fi.fic;
255 }
256 cache = fi.cache;
257#if defined(Q_OS_UNIX)
258 symLink = fi.symLink;
259#endif
260 return *this;
261}
262
263
264/*!
265 Sets the file that the QFileInfo provides information about to \a
266 file.
267
268 The \a file can also include an absolute or relative file path.
269 Absolute paths begin with the directory separator (e.g. "/" under
270 Unix) or a drive specification (under Windows and OS/2). Relative file
271 names begin with a directory name or a file name and specify a
272 path relative to the current directory.
273
274 Example:
275 \code
276 QString absolute = "/local/bin";
277 QString relative = "local/bin";
278 QFileInfo absFile( absolute );
279 QFileInfo relFile( relative );
280
281 QDir::setCurrent( QDir::rootDirPath() );
282 // absFile and relFile now point to the same file
283
284 QDir::setCurrent( "/tmp" );
285 // absFile now points to "/local/bin",
286 // while relFile points to "/tmp/local/bin"
287 \endcode
288
289 \sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
290*/
291
292void QFileInfo::setFile( const QString &file )
293{
294 fn = file;
295 slashify( fn );
296 delete fic;
297 fic = 0;
298}
299
300/*!
301 \overload
302
303 Sets the file that the QFileInfo provides information about to \a
304 file.
305
306 If \a file includes a relative path, the QFileInfo will also have
307 a relative path.
308
309 \sa isRelative()
310*/
311
312void QFileInfo::setFile( const QFile &file )
313{
314 fn = file.name();
315 slashify( fn );
316 delete fic;
317 fic = 0;
318}
319
320/*!
321 \overload
322
323 Sets the file that the QFileInfo provides information about to \a
324 fileName in directory \a d.
325
326 If \a fileName includes a relative path, the QFileInfo will also
327 have a relative path.
328
329 \sa isRelative()
330*/
331#ifndef QT_NO_DIR
332void QFileInfo::setFile( const QDir &d, const QString &fileName )
333{
334 fn = d.filePath( fileName );
335 slashify( fn );
336 delete fic;
337 fic = 0;
338}
339#endif
340
341/*!
342 Returns TRUE if the file exists; otherwise returns FALSE.
343*/
344
345bool QFileInfo::exists() const
346{
347 return qt_file_access( fn, F_OK );
348}
349
350/*!
351 Refreshes the information about the file, i.e. reads in information
352 from the file system the next time a cached property is fetched.
353
354 \sa setCaching()
355*/
356
357void QFileInfo::refresh() const
358{
359 QFileInfo *that = (QFileInfo*)this; // Mutable function
360 delete that->fic;
361 that->fic = 0;
362}
363
364/*!
365 \fn bool QFileInfo::caching() const
366
367 Returns TRUE if caching is enabled; otherwise returns FALSE.
368
369 \sa setCaching(), refresh()
370*/
371
372/*!
373 If \a enable is TRUE, enables caching of file information. If \a
374 enable is FALSE caching is disabled.
375
376 When caching is enabled, QFileInfo reads the file information from
377 the file system the first time it's needed, but generally not
378 later.
379
380 Caching is enabled by default.
381
382 \sa refresh(), caching()
383*/
384
385void QFileInfo::setCaching( bool enable )
386{
387 if ( cache == enable )
388 return;
389 cache = enable;
390 if ( cache ) {
391 delete fic;
392 fic = 0;
393 }
394}
395
396
397/*!
398 Returns the file name, including the path (which may be absolute
399 or relative).
400
401 \sa isRelative(), absFilePath()
402*/
403
404QString QFileInfo::filePath() const
405{
406 return fn;
407}
408
409/*!
410 Returns the base name of the file.
411
412 If \a complete is FALSE (the default) the base name consists of
413 all characters in the file name up to (but not including) the \e
414 first '.' character.
415
416 If \a complete is TRUE the base name consists of all characters in
417 the file up to (but not including) the \e last '.' character.
418
419 The path is not included in either case.
420
421 Example:
422 \code
423 QFileInfo fi( "/tmp/archive.tar.gz" );
424 QString base = fi.baseName(); // base = "archive"
425 base = fi.baseName( TRUE ); // base = "archive.tar"
426 \endcode
427
428 \sa fileName(), extension()
429*/
430
431QString QFileInfo::baseName( bool complete ) const
432{
433 QString tmp = fileName();
434 int pos = complete ? tmp.findRev( '.' ) : tmp.find( '.' );
435 if ( pos == -1 )
436 return tmp;
437 else
438 return tmp.left( pos );
439}
440
441/*!
442 Returns the file's extension name.
443
444 If \a complete is TRUE (the default), extension() returns the
445 string of all characters in the file name after (but not
446 including) the first '.' character.
447
448 If \a complete is FALSE, extension() returns the string of all
449 characters in the file name after (but not including) the last '.'
450 character.
451
452 Example:
453 \code
454 QFileInfo fi( "/tmp/archive.tar.gz" );
455 QString ext = fi.extension(); // ext = "tar.gz"
456 ext = fi.extension( FALSE ); // ext = "gz"
457 \endcode
458
459 \sa fileName(), baseName()
460*/
461
462QString QFileInfo::extension( bool complete ) const
463{
464 QString s = fileName();
465 int pos = complete ? s.find( '.' ) : s.findRev( '.' );
466 if ( pos < 0 )
467 return QString::fromLatin1( "" );
468 else
469 return s.right( s.length() - pos - 1 );
470}
471
472/*!
473 Returns the file's path as a QDir object.
474
475 If the QFileInfo is relative and \a absPath is FALSE, the QDir
476 will be relative; otherwise it will be absolute.
477
478 \sa dirPath(), filePath(), fileName(), isRelative()
479*/
480#ifndef QT_NO_DIR
481QDir QFileInfo::dir( bool absPath ) const
482{
483 return QDir( dirPath(absPath) );
484}
485#endif
486
487
488/*!
489 Returns TRUE if the file is readable; otherwise returns FALSE.
490
491 \sa isWritable(), isExecutable(), permission()
492*/
493
494bool QFileInfo::isReadable() const
495{
496#ifdef Q_WS_WIN
497 return qt_file_access( fn, R_OK ) && permission( ReadUser );
498#else
499 return qt_file_access( fn, R_OK );
500#endif
501}
502
503/*!
504 Returns TRUE if the file is writable; otherwise returns FALSE.
505
506 \sa isReadable(), isExecutable(), permission()
507*/
508
509bool QFileInfo::isWritable() const
510{
511#ifdef Q_WS_WIN
512 return qt_file_access( fn, W_OK ) && permission( WriteUser );
513#else
514 return qt_file_access( fn, W_OK );
515#endif
516}
517
518/*!
519 Returns TRUE if the file is executable; otherwise returns FALSE.
520
521 \sa isReadable(), isWritable(), permission()
522*/
523
524bool QFileInfo::isExecutable() const
525{
526#ifdef Q_WS_WIN
527 return qt_file_access( fn, X_OK ) && permission( ExeUser );
528#else
529 return qt_file_access( fn, X_OK );
530#endif
531}
532
533#if !defined(Q_WS_WIN) && !defined(Q_OS_OS2)
534bool QFileInfo::isHidden() const
535{
536 return fileName()[ 0 ] == QChar( '.' );
537}
538#endif
539
540/*!
541 Returns TRUE if the file path name is relative. Returns FALSE if
542 the path is absolute (e.g. under Unix a path is absolute if it
543 begins with a "/").
544*/
545#ifndef QT_NO_DIR
546bool QFileInfo::isRelative() const
547{
548 return QDir::isRelativePath( fn );
549}
550
551/*!
552 Converts the file's path to an absolute path.
553
554 If it is already absolute, nothing is done.
555
556 \sa filePath(), isRelative()
557*/
558
559bool QFileInfo::convertToAbs()
560{
561 if ( isRelative() )
562 fn = absFilePath();
563 return QDir::isRelativePath( fn );
564}
565#endif
566
567/*!
568 Returns the file size in bytes, or 0 if the file does not exist or
569 if the size is 0 or if the size cannot be fetched.
570*/
571#if defined(QT_ABI_QT4)
572QIODevice::Offset QFileInfo::size() const
573#else
574uint QFileInfo::size() const
575#endif
576{
577 if ( !fic || !cache )
578 doStat();
579 if ( fic )
580#if defined(QT_ABI_QT4)
581 return (QIODevice::Offset)fic->st.st_size;
582#elif defined(QT_LARGEFILE_SUPPORT)
583 return (uint)fic->st.st_size > UINT_MAX ? UINT_MAX : (uint)fic->st.st_size;
584#else
585 return (uint)fic->st.st_size;
586#endif
587 else
588 return 0;
589}
590
591/*!
592 Returns the date and time when the file was created.
593
594 On platforms where this information is not available, returns the
595 same as lastModified().
596
597 \sa created() lastModified() lastRead()
598*/
599
600QDateTime QFileInfo::created() const
601{
602 QDateTime dt;
603 if ( !fic || !cache )
604 doStat();
605 if ( fic && fic->st.st_ctime != 0 ) {
606 dt.setTime_t( fic->st.st_ctime );
607 return dt;
608 } else {
609 return lastModified();
610 }
611}
612
613/*!
614 Returns the date and time when the file was last modified.
615
616 \sa created() lastModified() lastRead()
617*/
618
619QDateTime QFileInfo::lastModified() const
620{
621 QDateTime dt;
622 if ( !fic || !cache )
623 doStat();
624 if ( fic )
625 dt.setTime_t( fic->st.st_mtime );
626 return dt;
627}
628
629/*!
630 Returns the date and time when the file was last read (accessed).
631
632 On platforms where this information is not available, returns the
633 same as lastModified().
634
635 \sa created() lastModified() lastRead()
636*/
637
638QDateTime QFileInfo::lastRead() const
639{
640 QDateTime dt;
641 if ( !fic || !cache )
642 doStat();
643 if ( fic && fic->st.st_atime != 0 ) {
644 dt.setTime_t( fic->st.st_atime );
645 return dt;
646 } else {
647 return lastModified();
648 }
649}
650
651#ifndef QT_NO_DIR
652
653/*!
654 Returns the absolute path including the file name.
655
656 The absolute path name consists of the full path and the file
657 name. On Unix this will always begin with the root, '/',
658 directory. On Windows and OS/2 this will always begin 'D:/' where D is a
659 drive letter, except for network shares that are not mapped to a
660 drive letter, in which case the path will begin '//sharename/'.
661
662 This function returns the same as filePath(), unless isRelative()
663 is TRUE.
664
665 If the QFileInfo is empty it returns QDir::currentDirPath().
666
667 This function can be time consuming under Unix (in the order of
668 milliseconds).
669
670 \sa isRelative(), filePath()
671*/
672QString QFileInfo::absFilePath() const
673{
674 QString tmp;
675 if ( QDir::isRelativePath(fn)
676#if defined(Q_OS_WIN32) || defined(Q_OS_OS2)
677 && fn[1] != ':'
678#endif
679 ) {
680 tmp = QDir::currentDirPath();
681 tmp += '/';
682 }
683 tmp += fn;
684 makeAbs( tmp );
685 return QDir::cleanDirPath( tmp );
686}
687
688/*! \internal
689 Detaches all internal data.
690*/
691void QFileInfo::detach()
692{
693 fn = QDeepCopy<QString>( fn );
694 if ( fic ) {
695 QFileInfoCache *cur = fic;
696 fic = new QFileInfoCache;
697 *fic = *cur;
698 delete cur;
699 }
700}
701
702#endif
Note: See TracBrowser for help on using the repository browser.