source: trunk/src/corelib/io/qfile.cpp@ 427

Last change on this file since 427 was 172, checked in by Dmitry A. Kuminov, 16 years ago

corelib/io, gui/dialogs: Handle DOS-like filesystem details (drives, slashes) on OS/2 similarly to Win32.

File size: 44.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qplatformdefs.h"
43#include "qdebug.h"
44#include "qfile.h"
45#include "qfsfileengine.h"
46#include "qtemporaryfile.h"
47#include "qlist.h"
48#include "qfileinfo.h"
49#include "private/qiodevice_p.h"
50#include "private/qfile_p.h"
51#if defined(QT_BUILD_CORE_LIB)
52# include "qcoreapplication.h"
53#endif
54
55#if !defined(Q_OS_WINCE)
56#include <errno.h>
57#endif
58
59#ifdef QT_NO_QOBJECT
60#define tr(X) QString::fromLatin1(X)
61#endif
62
63QT_BEGIN_NAMESPACE
64
65static const int QFILE_WRITEBUFFER_SIZE = 16384;
66
67static QByteArray locale_encode(const QString &f)
68{
69#ifndef Q_OS_DARWIN
70 return f.toLocal8Bit();
71#else
72 // Mac always expects UTF-8... and decomposed...
73 return f.normalized(QString::NormalizationForm_D).toUtf8();
74#endif
75}
76
77static QString locale_decode(const QByteArray &f)
78{
79#ifndef Q_OS_DARWIN
80 return QString::fromLocal8Bit(f);
81#else
82 // Mac always gives us UTF-8 and decomposed, we want that composed...
83 return QString::fromUtf8(f).normalized(QString::NormalizationForm_C);
84#endif
85}
86
87//************* QFilePrivate
88QFile::EncoderFn QFilePrivate::encoder = locale_encode;
89QFile::DecoderFn QFilePrivate::decoder = locale_decode;
90
91QFilePrivate::QFilePrivate()
92 : fileEngine(0), lastWasWrite(false),
93 writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError)
94{
95}
96
97QFilePrivate::~QFilePrivate()
98{
99 delete fileEngine;
100 fileEngine = 0;
101}
102
103bool
104QFilePrivate::openExternalFile(int flags, int fd)
105{
106#ifdef QT_NO_FSFILEENGINE
107 Q_UNUSED(flags);
108 Q_UNUSED(fd);
109 return false;
110#else
111 delete fileEngine;
112 QFSFileEngine *fe = new QFSFileEngine;
113 fe->setFileName(fileName);
114 fileEngine = fe;
115 return fe->open(QIODevice::OpenMode(flags), fd);
116#endif
117}
118
119bool
120QFilePrivate::openExternalFile(int flags, FILE *fh)
121{
122#ifdef QT_NO_FSFILEENGINE
123 Q_UNUSED(flags);
124 Q_UNUSED(fh);
125 return false;
126#else
127 delete fileEngine;
128 QFSFileEngine *fe = new QFSFileEngine;
129 fe->setFileName(fileName);
130 fileEngine = fe;
131 return fe->open(QIODevice::OpenMode(flags), fh);
132#endif
133}
134
135inline bool QFilePrivate::ensureFlushed() const
136{
137 // This function ensures that the write buffer has been flushed (const
138 // because certain const functions need to call it.
139 if (lastWasWrite) {
140 const_cast<QFilePrivate *>(this)->lastWasWrite = false;
141 if (!const_cast<QFile *>(q_func())->flush())
142 return false;
143 }
144 return true;
145}
146
147void
148QFilePrivate::setError(QFile::FileError err)
149{
150 error = err;
151 errorString.clear();
152}
153
154void
155QFilePrivate::setError(QFile::FileError err, const QString &errStr)
156{
157 Q_Q(QFile);
158 error = err;
159 q->setErrorString(errStr);
160}
161
162void
163QFilePrivate::setError(QFile::FileError err, int errNum)
164{
165 Q_Q(QFile);
166 error = err;
167 q->setErrorString(qt_error_string(errNum));
168}
169
170//************* QFile
171
172/*!
173 \class QFile
174 \brief The QFile class provides an interface for reading from and writing to files.
175
176 \ingroup io
177 \mainclass
178 \reentrant
179
180 QFile is an I/O device for reading and writing text and binary
181 files and \l{The Qt Resource System}{resources}. A QFile may be
182 used by itself or, more conveniently, with a QTextStream or
183 QDataStream.
184
185 The file name is usually passed in the constructor, but it can be
186 set at any time using setFileName(). QFile expects the file
187 separator to be '/' regardless of operating system. The use of
188 other separators (e.g., '\\') is not supported.
189
190 You can check for a file's existence using exists(), and remove a
191 file using remove(). (More advanced file system related operations
192 are provided by QFileInfo and QDir.)
193
194 The file is opened with open(), closed with close(), and flushed
195 with flush(). Data is usually read and written using QDataStream
196 or QTextStream, but you can also call the QIODevice-inherited
197 functions read(), readLine(), readAll(), write(). QFile also
198 inherits getChar(), putChar(), and ungetChar(), which work one
199 character at a time.
200
201 The size of the file is returned by size(). You can get the
202 current file position using pos(), or move to a new file position
203 using seek(). If you've reached the end of the file, atEnd()
204 returns true.
205
206 \section1 Reading Files Directly
207
208 The following example reads a text file line by line:
209
210 \snippet doc/src/snippets/file/file.cpp 0
211
212 The QIODevice::Text flag passed to open() tells Qt to convert
213 Windows-style line terminators ("\\r\\n") into C++-style
214 terminators ("\\n"). By default, QFile assumes binary, i.e. it
215 doesn't perform any conversion on the bytes stored in the file.
216
217 \section1 Using Streams to Read Files
218
219 The next example uses QTextStream to read a text file
220 line by line:
221
222 \snippet doc/src/snippets/file/file.cpp 1
223
224 QTextStream takes care of converting the 8-bit data stored on
225 disk into a 16-bit Unicode QString. By default, it assumes that
226 the user system's local 8-bit encoding is used (e.g., ISO 8859-1
227 for most of Europe; see QTextCodec::codecForLocale() for
228 details). This can be changed using setCodec().
229
230 To write text, we can use operator<<(), which is overloaded to
231 take a QTextStream on the left and various data types (including
232 QString) on the right:
233
234 \snippet doc/src/snippets/file/file.cpp 2
235
236 QDataStream is similar, in that you can use operator<<() to write
237 data and operator>>() to read it back. See the class
238 documentation for details.
239
240 When you use QFile, QFileInfo, and QDir to access the file system
241 with Qt, you can use Unicode file names. On Unix, these file
242 names are converted to an 8-bit encoding. If you want to use
243 standard C++ APIs (\c <cstdio> or \c <iostream>) or
244 platform-specific APIs to access files instead of QFile, you can
245 use the encodeName() and decodeName() functions to convert
246 between Unicode file names and 8-bit file names.
247
248 On Unix, there are some special system files (e.g. in \c /proc) for which
249 size() will always return 0, yet you may still be able to read more data
250 from such a file; the data is generated in direct response to you calling
251 read(). In this case, however, you cannot use atEnd() to determine if
252 there is more data to read (since atEnd() will return true for a file that
253 claims to have size 0). Instead, you should either call readAll(), or call
254 read() or readLine() repeatedly until no more data can be read. The next
255 example uses QTextStream to read \c /proc/modules line by line:
256
257 \snippet doc/src/snippets/file/file.cpp 3
258
259 \section1 Signals
260
261 Unlike other QIODevice implementations, such as QTcpSocket, QFile does not
262 emit the aboutToClose(), bytesWritten(), or readyRead() signals. This
263 implementation detail means that QFile is not suitable for reading and
264 writing certain types of files, such as device files on Unix platforms.
265
266 \section1 Platform Specific Issues
267
268 File permissions are handled differently on Linux/Mac OS X and
269 Windows. In a non \l{QIODevice::isWritable()}{writable}
270 directory on Linux, files cannot be created. This is not always
271 the case on Windows, where, for instance, the 'My Documents'
272 directory usually is not writable, but it is still possible to
273 create files in it.
274
275 \sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System}
276*/
277
278/*!
279 \enum QFile::FileError
280
281 This enum describes the errors that may be returned by the error()
282 function.
283
284 \value NoError No error occurred.
285 \value ReadError An error occurred when reading from the file.
286 \value WriteError An error occurred when writing to the file.
287 \value FatalError A fatal error occurred.
288 \value ResourceError
289 \value OpenError The file could not be opened.
290 \value AbortError The operation was aborted.
291 \value TimeOutError A timeout occurred.
292 \value UnspecifiedError An unspecified error occurred.
293 \value RemoveError The file could not be removed.
294 \value RenameError The file could not be renamed.
295 \value PositionError The position in the file could not be changed.
296 \value ResizeError The file could not be resized.
297 \value PermissionsError The file could not be accessed.
298 \value CopyError The file could not be copied.
299
300 \omitvalue ConnectError
301*/
302
303/*!
304 \enum QFile::Permission
305
306 This enum is used by the permission() function to report the
307 permissions and ownership of a file. The values may be OR-ed
308 together to test multiple permissions and ownership values.
309
310 \value ReadOwner The file is readable by the owner of the file.
311 \value WriteOwner The file is writable by the owner of the file.
312 \value ExeOwner The file is executable by the owner of the file.
313 \value ReadUser The file is readable by the user.
314 \value WriteUser The file is writable by the user.
315 \value ExeUser The file is executable by the user.
316 \value ReadGroup The file is readable by the group.
317 \value WriteGroup The file is writable by the group.
318 \value ExeGroup The file is executable by the group.
319 \value ReadOther The file is readable by anyone.
320 \value WriteOther The file is writable by anyone.
321 \value ExeOther The file is executable by anyone.
322
323 \warning Because of differences in the platforms supported by Qt,
324 the semantics of ReadUser, WriteUser and ExeUser are
325 platform-dependent: On Unix, the rights of the owner of the file
326 are returned and on Windows the rights of the current user are
327 returned. This behavior might change in a future Qt version.
328
329 Note that Qt does not by default check for permissions on NTFS
330 file systems, as this may decrease the performance of file
331 handling considerably. It is possible to force permission checking
332 on NTFS by including the following code in your source:
333
334 \snippet doc/src/snippets/ntfsp.cpp 0
335
336 Permission checking is then turned on and off by incrementing and
337 decrementing \c qt_ntfs_permission_lookup by 1.
338
339 \snippet doc/src/snippets/ntfsp.cpp 1
340*/
341
342#ifdef QT3_SUPPORT
343/*!
344 \typedef QFile::PermissionSpec
345
346 Use QFile::Permission instead.
347*/
348#endif
349
350#ifdef QT_NO_QOBJECT
351QFile::QFile()
352 : QIODevice(*new QFilePrivate)
353{
354}
355QFile::QFile(const QString &name)
356 : QIODevice(*new QFilePrivate)
357{
358 d_func()->fileName = name;
359}
360QFile::QFile(QFilePrivate &dd)
361 : QIODevice(dd)
362{
363}
364#else
365/*!
366 \internal
367*/
368QFile::QFile()
369 : QIODevice(*new QFilePrivate, 0)
370{
371}
372/*!
373 Constructs a new file object with the given \a parent.
374*/
375QFile::QFile(QObject *parent)
376 : QIODevice(*new QFilePrivate, parent)
377{
378}
379/*!
380 Constructs a new file object to represent the file with the given \a name.
381*/
382QFile::QFile(const QString &name)
383 : QIODevice(*new QFilePrivate, 0)
384{
385 Q_D(QFile);
386 d->fileName = name;
387}
388/*!
389 Constructs a new file object with the given \a parent to represent the
390 file with the specified \a name.
391*/
392QFile::QFile(const QString &name, QObject *parent)
393 : QIODevice(*new QFilePrivate, parent)
394{
395 Q_D(QFile);
396 d->fileName = name;
397}
398/*!
399 \internal
400*/
401QFile::QFile(QFilePrivate &dd, QObject *parent)
402 : QIODevice(dd, parent)
403{
404}
405#endif
406
407/*!
408 Destroys the file object, closing it if necessary.
409*/
410QFile::~QFile()
411{
412 close();
413#ifdef QT_NO_QOBJECT
414 delete d_ptr;
415#endif
416}
417
418/*!
419 Returns the name set by setFileName() or to the QFile
420 constructors.
421
422 \sa setFileName(), QFileInfo::fileName()
423*/
424QString QFile::fileName() const
425{
426 return fileEngine()->fileName(QAbstractFileEngine::DefaultName);
427}
428
429/*!
430 Sets the \a name of the file. The name can have no path, a
431 relative path, or an absolute path.
432
433 Do not call this function if the file has already been opened.
434
435 If the file name has no path or a relative path, the path used
436 will be the application's current directory path
437 \e{at the time of the open()} call.
438
439 Example:
440 \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 0
441
442 Note that the directory separator "/" works for all operating
443 systems supported by Qt.
444
445 \sa fileName(), QFileInfo, QDir
446*/
447void
448QFile::setFileName(const QString &name)
449{
450 Q_D(QFile);
451 if (isOpen()) {
452 qWarning("QFile::setFileName: File (%s) is already opened",
453 qPrintable(fileName()));
454 close();
455 }
456 if(d->fileEngine) { //get a new file engine later
457 delete d->fileEngine;
458 d->fileEngine = 0;
459 }
460 d->fileName = name;
461}
462
463/*!
464 \fn QString QFile::decodeName(const char *localFileName)
465
466 \overload
467
468 Returns the Unicode version of the given \a localFileName. See
469 encodeName() for details.
470*/
471
472/*!
473 By default, this function converts \a fileName to the local 8-bit
474 encoding determined by the user's locale. This is sufficient for
475 file names that the user chooses. File names hard-coded into the
476 application should only use 7-bit ASCII filename characters.
477
478 \sa decodeName() setEncodingFunction()
479*/
480
481QByteArray
482QFile::encodeName(const QString &fileName)
483{
484 return (*QFilePrivate::encoder)(fileName);
485}
486
487/*!
488 \typedef QFile::EncoderFn
489
490 This is a typedef for a pointer to a function with the following
491 signature:
492
493 \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 1
494
495 \sa setEncodingFunction(), encodeName()
496*/
497
498/*!
499 This does the reverse of QFile::encodeName() using \a localFileName.
500
501 \sa setDecodingFunction(), encodeName()
502*/
503
504QString
505QFile::decodeName(const QByteArray &localFileName)
506{
507 return (*QFilePrivate::decoder)(localFileName);
508}
509
510/*!
511 \fn void QFile::setEncodingFunction(EncoderFn function)
512
513 \nonreentrant
514
515 Sets the \a function for encoding Unicode file names. The
516 default encodes in the locale-specific 8-bit encoding.
517
518 \sa encodeName(), setDecodingFunction()
519*/
520
521void
522QFile::setEncodingFunction(EncoderFn f)
523{
524 if (!f)
525 f = locale_encode;
526 QFilePrivate::encoder = f;
527}
528
529/*!
530 \typedef QFile::DecoderFn
531
532 This is a typedef for a pointer to a function with the following
533 signature:
534
535 \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 2
536
537 \sa setDecodingFunction()
538*/
539
540/*!
541 \fn void QFile::setDecodingFunction(DecoderFn function)
542
543 \nonreentrant
544
545 Sets the \a function for decoding 8-bit file names. The
546 default uses the locale-specific 8-bit encoding.
547
548 \sa setEncodingFunction(), decodeName()
549*/
550
551void
552QFile::setDecodingFunction(DecoderFn f)
553{
554 if (!f)
555 f = locale_decode;
556 QFilePrivate::decoder = f;
557}
558
559/*!
560 \overload
561
562 Returns true if the file specified by fileName() exists; otherwise
563 returns false.
564
565 \sa fileName(), setFileName()
566*/
567
568bool
569QFile::exists() const
570{
571 // 0x1000000 = QAbstractFileEngine::Refresh, forcing an update
572 return (fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask
573 | QAbstractFileEngine::FileFlag(0x1000000)) & QAbstractFileEngine::ExistsFlag);
574}
575
576/*!
577 Returns true if the file specified by \a fileName exists; otherwise
578 returns false.
579*/
580
581bool
582QFile::exists(const QString &fileName)
583{
584 return QFileInfo(fileName).exists();
585}
586
587/*!
588 \fn QString QFile::symLinkTarget() const
589 \since 4.2
590 \overload
591
592 Returns the absolute path of the file or directory a symlink (or shortcut
593 on Windows) points to, or a an empty string if the object isn't a symbolic
594 link.
595
596 This name may not represent an existing file; it is only a string.
597 QFile::exists() returns true if the symlink points to an existing file.
598
599 \sa fileName() setFileName()
600*/
601
602/*!
603 \obsolete
604
605 Use symLinkTarget() instead.
606*/
607QString
608QFile::readLink() const
609{
610 return fileEngine()->fileName(QAbstractFileEngine::LinkName);
611}
612
613/*!
614 \fn static QString QFile::symLinkTarget(const QString &fileName)
615 \since 4.2
616
617 Returns the absolute path of the file or directory referred to by the
618 symlink (or shortcut on Windows) specified by \a fileName, or returns an
619 empty string if the \a fileName does not correspond to a symbolic link.
620
621 This name may not represent an existing file; it is only a string.
622 QFile::exists() returns true if the symlink points to an existing file.
623*/
624
625/*!
626 \obsolete
627
628 Use symLinkTarget() instead.
629*/
630QString
631QFile::readLink(const QString &fileName)
632{
633 return QFileInfo(fileName).readLink();
634}
635
636/*!
637 Removes the file specified by fileName(). Returns true if successful;
638 otherwise returns false.
639
640 The file is closed before it is removed.
641
642 \sa setFileName()
643*/
644
645bool
646QFile::remove()
647{
648 Q_D(QFile);
649 if (d->fileName.isEmpty()) {
650 qWarning("QFile::remove: Empty or null file name");
651 return false;
652 }
653 close();
654 if(error() == QFile::NoError) {
655 if(fileEngine()->remove()) {
656 unsetError();
657 return true;
658 }
659#if defined(Q_OS_WIN)
660 d->setError(QFile::RemoveError, GetLastError());
661#else
662 d->setError(QFile::RemoveError, errno);
663#endif
664 }
665 return false;
666}
667
668/*!
669 \overload
670
671 Removes the file specified by the \a fileName given.
672
673 Returns true if successful; otherwise returns false.
674
675 \sa remove()
676*/
677
678bool
679QFile::remove(const QString &fileName)
680{
681 return QFile(fileName).remove();
682}
683
684/*!
685 Renames the file currently specified by fileName() to \a newName.
686 Returns true if successful; otherwise returns false.
687
688 If a file with the name \a newName already exists, rename() returns false
689 (i.e., QFile will not overwrite it).
690
691 The file is closed before it is renamed.
692
693 \sa setFileName()
694*/
695
696bool
697QFile::rename(const QString &newName)
698{
699 Q_D(QFile);
700 if (d->fileName.isEmpty()) {
701 qWarning("QFile::rename: Empty or null file name");
702 return false;
703 }
704 if (QFile(newName).exists()) {
705 // ### Race condition. If a file is moved in after this, it /will/ be
706 // overwritten. On Unix, the proper solution is to use hardlinks:
707 // return ::link(old, new) && ::remove(old);
708 d->setError(QFile::RenameError, tr("Destination file exists"));
709 return false;
710 }
711 close();
712 if(error() == QFile::NoError) {
713 if (fileEngine()->rename(newName)) {
714 unsetError();
715 // engine was able to handle the new name so we just reset it
716 fileEngine()->setFileName(newName);
717 d->fileName = newName;
718 return true;
719 }
720
721 QFile in(fileName());
722 QFile out(newName);
723 if (in.open(QIODevice::ReadOnly)) {
724 if (out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
725 bool error = false;
726 char block[4096];
727 qint64 read;
728 while ((read = in.read(block, sizeof(block))) > 0) {
729 if (read != out.write(block, read)) {
730 d->setError(QFile::RenameError, out.errorString());
731 error = true;
732 break;
733 }
734 }
735 if (read == -1) {
736 d->setError(QFile::RenameError, in.errorString());
737 error = true;
738 }
739 if(!error) {
740 if (!in.remove()) {
741 d->setError(QFile::RenameError, tr("Cannot remove source file"));
742 error = true;
743 }
744 }
745 if (error)
746 out.remove();
747 else
748 setFileName(newName);
749 return !error;
750 }
751 }
752 d->setError(QFile::RenameError, out.isOpen() ? in.errorString() : out.errorString());
753 }
754 return false;
755}
756
757/*!
758 \overload
759
760 Renames the file \a oldName to \a newName. Returns true if
761 successful; otherwise returns false.
762
763 If a file with the name \a newName already exists, rename() returns false
764 (i.e., QFile will not overwrite it).
765
766 \sa rename()
767*/
768
769bool
770QFile::rename(const QString &oldName, const QString &newName)
771{
772 return QFile(oldName).rename(newName);
773}
774
775/*!
776
777 Creates a link named \a linkName that points to the file currently specified by
778 fileName(). What a link is depends on the underlying filesystem (be it a
779 shortcut on Windows or a symbolic link on Unix). Returns true if successful;
780 otherwise returns false.
781
782 This function will not overwrite an already existing entity in the file system;
783 in this case, \c link() will return false and set \l{QFile::}{error()} to
784 return \l{QFile::}{RenameError}.
785
786 \note To create a valid link on Windows, \a linkName must have a \c{.lnk} file extension.
787
788 \sa setFileName()
789*/
790
791bool
792QFile::link(const QString &linkName)
793{
794 Q_D(QFile);
795 if (d->fileName.isEmpty()) {
796 qWarning("QFile::link: Empty or null file name");
797 return false;
798 }
799 QFileInfo fi(linkName);
800 if(fileEngine()->link(fi.absoluteFilePath())) {
801 unsetError();
802 return true;
803 }
804 d->setError(QFile::RenameError, errno);
805 return false;
806}
807
808/*!
809 \overload
810
811 Creates a link named \a linkName that points to the file \a fileName. What a link is
812 depends on the underlying filesystem (be it a shortcut on Windows
813 or a symbolic link on Unix). Returns true if successful; otherwise
814 returns false.
815
816 \sa link()
817*/
818
819bool
820QFile::link(const QString &fileName, const QString &linkName)
821{
822 return QFile(fileName).link(linkName);
823}
824
825/*!
826 Copies the file currently specified by fileName() to a file called
827 \a newName. Returns true if successful; otherwise returns false.
828
829 Note that if a file with the name \a newName already exists,
830 copy() returns false (i.e. QFile will not overwrite it).
831
832 The source file is closed before it is copied.
833
834 \sa setFileName()
835*/
836
837bool
838QFile::copy(const QString &newName)
839{
840 Q_D(QFile);
841 if (d->fileName.isEmpty()) {
842 qWarning("QFile::copy: Empty or null file name");
843 return false;
844 }
845 if (QFile(newName).exists()) {
846 // ### Race condition. If a file is moved in after this, it /will/ be
847 // overwritten. On Unix, the proper solution is to use hardlinks:
848 // return ::link(old, new) && ::remove(old); See also rename().
849 d->setError(QFile::CopyError, tr("Destination file exists"));
850 return false;
851 }
852 close();
853 if(error() == QFile::NoError) {
854 if(fileEngine()->copy(newName)) {
855 unsetError();
856 return true;
857 } else {
858 bool error = false;
859 if(!open(QFile::ReadOnly)) {
860 error = true;
861 d->setError(QFile::CopyError, tr("Cannot open %1 for input").arg(d->fileName));
862 } else {
863 QString fileTemplate = QLatin1String("%1/qt_temp.XXXXXX");
864#ifdef QT_NO_TEMPORARYFILE
865 QFile out(fileTemplate.arg(QFileInfo(newName).path()));
866 if (!out.open(QIODevice::ReadWrite))
867 error = true;
868#else
869 QTemporaryFile out(fileTemplate.arg(QFileInfo(newName).path()));
870 if (!out.open()) {
871 out.setFileTemplate(fileTemplate.arg(QDir::tempPath()));
872 if (!out.open())
873 error = true;
874 }
875#endif
876 if (error) {
877 out.close();
878 d->setError(QFile::CopyError, tr("Cannot open for output"));
879 } else {
880 char block[4096];
881 qint64 totalRead = 0;
882 while(!atEnd()) {
883 qint64 in = read(block, sizeof(block));
884 if (in <= 0)
885 break;
886 totalRead += in;
887 if(in != out.write(block, in)) {
888 d->setError(QFile::CopyError, tr("Failure to write block"));
889 error = true;
890 break;
891 }
892 }
893
894 if (totalRead != size()) {
895 // Unable to read from the source. The error string is
896 // already set from read().
897 error = true;
898 }
899 if (!error && !out.rename(newName)) {
900 error = true;
901 d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName));
902 }
903#ifdef QT_NO_TEMPORARYFILE
904 if (error)
905 out.remove();
906#else
907 if (!error)
908 out.setAutoRemove(false);
909#endif
910 }
911 }
912 if(!error) {
913 QFile::setPermissions(newName, permissions());
914 unsetError();
915 return true;
916 }
917 }
918 }
919 return false;
920}
921
922/*!
923 \overload
924
925 Copies the file \a fileName to \a newName. Returns true if successful;
926 otherwise returns false.
927
928 If a file with the name \a newName already exists, copy() returns false
929 (i.e., QFile will not overwrite it).
930
931 \sa rename()
932*/
933
934bool
935QFile::copy(const QString &fileName, const QString &newName)
936{
937 return QFile(fileName).copy(newName);
938}
939
940/*!
941 Returns true if the file can only be manipulated sequentially;
942 otherwise returns false.
943
944 Most files support random-access, but some special files may not.
945
946 \sa QIODevice::isSequential()
947*/
948bool QFile::isSequential() const
949{
950 Q_D(const QFile);
951 return d->fileEngine && d->fileEngine->isSequential();
952}
953
954/*!
955 Opens the file using OpenMode \a mode, returning true if successful;
956 otherwise false.
957
958 The \a mode must be QIODevice::ReadOnly, QIODevice::WriteOnly, or
959 QIODevice::ReadWrite. It may also have additional flags, such as
960 QIODevice::Text and QIODevice::Unbuffered.
961
962 \note In \l{QIODevice::}{WriteOnly} or \l{QIODevice::}{ReadWrite}
963 mode, if the relevant file does not already exist, this function
964 will try to create a new file before opening it.
965
966 \note Because of limitations in the native API, QFile ignores the
967 Unbuffered flag on Windows.
968
969 \sa QIODevice::OpenMode, setFileName()
970*/
971bool QFile::open(OpenMode mode)
972{
973 Q_D(QFile);
974 if (isOpen()) {
975 qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
976 return false;
977 }
978 if (mode & Append)
979 mode |= WriteOnly;
980
981 unsetError();
982 if ((mode & (ReadOnly | WriteOnly)) == 0) {
983 qWarning("QIODevice::open: File access not specified");
984 return false;
985 }
986 if (fileEngine()->open(mode)) {
987 QIODevice::open(mode);
988 if (mode & Append)
989 seek(size());
990 return true;
991 }
992 QFile::FileError err = fileEngine()->error();
993 if(err == QFile::UnspecifiedError)
994 err = QFile::OpenError;
995 d->setError(err, fileEngine()->errorString());
996 return false;
997}
998
999/*! \fn QFile::open(OpenMode, FILE*)
1000
1001 Use open(FILE *, OpenMode) instead.
1002*/
1003
1004/*!
1005 \overload
1006
1007 Opens the existing file handle \a fh in the given \a mode.
1008 Returns true if successful; otherwise returns false.
1009
1010 Example:
1011 \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 3
1012
1013 When a QFile is opened using this function, close() does not actually
1014 close the file, but only flushes it.
1015
1016 \bold{Warning:}
1017 \list 1
1018 \o If \a fh is \c stdin, \c stdout, or \c stderr, you may not be able
1019 to seek(). See QIODevice::isSequentialAccess() for more information.
1020 \o Since this function opens the file without specifying the file name,
1021 you cannot use this QFile with a QFileInfo.
1022 \endlist
1023
1024 \note For Windows CE you may not be able to call seek() and resize().
1025 Also, size() is set to \c 0.
1026
1027 \sa close(), {qmake Variable Reference#CONFIG}{qmake Variable Reference}
1028
1029 \bold{Note for the Windows Platform}
1030
1031 \a fh must be opened in binary mode (i.e., the mode string must contain
1032 'b', as in "rb" or "wb") when accessing files and other random-access
1033 devices. Qt will translate the end-of-line characters if you pass
1034 QIODevice::Text to \a mode. Sequential devices, such as stdin and stdout,
1035 are unaffected by this limitation.
1036
1037 You need to enable support for console applications in order to use the
1038 stdin, stdout and stderr streams at the console. To do this, add the
1039 following declaration to your application's project file:
1040
1041 \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 4
1042*/
1043bool QFile::open(FILE *fh, OpenMode mode)
1044{
1045 Q_D(QFile);
1046 if (isOpen()) {
1047 qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
1048 return false;
1049 }
1050 if (mode & Append)
1051 mode |= WriteOnly;
1052 unsetError();
1053 if ((mode & (ReadOnly | WriteOnly)) == 0) {
1054 qWarning("QFile::open: File access not specified");
1055 return false;
1056 }
1057 if(d->openExternalFile(mode, fh)) {
1058 QIODevice::open(mode);
1059 if (mode & Append) {
1060 seek(size());
1061 } else {
1062 long pos = ftell(fh);
1063 if (pos != -1)
1064 seek(pos);
1065 }
1066 return true;
1067 }
1068 return false;
1069}
1070
1071/*! \fn QFile::open(OpenMode, int)
1072
1073 Use open(int, OpenMode) instead.
1074*/
1075
1076/*!
1077 \overload
1078
1079 Opens the existing file descripter \a fd in the given \a mode.
1080 Returns true if successful; otherwise returns false.
1081
1082 When a QFile is opened using this function, close() does not
1083 actually close the file.
1084
1085 The QFile that is opened using this function is automatically set
1086 to be in raw mode; this means that the file input/output functions
1087 are slow. If you run into performance issues, you should try to
1088 use one of the other open functions.
1089
1090 \warning If \a fd is 0 (\c stdin), 1 (\c stdout), or 2 (\c
1091 stderr), you may not be able to seek(). size() is set to \c
1092 LLONG_MAX (in \c <climits>).
1093
1094 \warning For Windows CE you may not be able to call seek(), setSize(),
1095 fileTime(). size() is set to \c 0.
1096
1097 \warning Since this function opens the file without specifying the file name,
1098 you cannot use this QFile with a QFileInfo.
1099
1100 \sa close()
1101*/
1102bool QFile::open(int fd, OpenMode mode)
1103{
1104 Q_D(QFile);
1105 if (isOpen()) {
1106 qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
1107 return false;
1108 }
1109 if (mode & Append)
1110 mode |= WriteOnly;
1111 unsetError();
1112 if ((mode & (ReadOnly | WriteOnly)) == 0) {
1113 qWarning("QFile::open: File access not specified");
1114 return false;
1115 }
1116 if(d->openExternalFile(mode, fd)) {
1117 QIODevice::open(mode);
1118 if (mode & Append)
1119 seek(size());
1120 return true;
1121 }
1122 return false;
1123}
1124
1125/*!
1126 Returns the file handle of the file.
1127
1128 This is a small positive integer, suitable for use with C library
1129 functions such as fdopen() and fcntl(). On systems that use file
1130 descriptors for sockets (i.e. Unix systems, but not Windows) the handle
1131 can be used with QSocketNotifier as well.
1132
1133 If the file is not open, or there is an error, handle() returns -1.
1134
1135 This function is not supported on Windows CE.
1136
1137 \sa QSocketNotifier
1138*/
1139
1140int
1141QFile::handle() const
1142{
1143 if (!isOpen())
1144 return -1;
1145
1146 if (QAbstractFileEngine *engine = fileEngine())
1147 return engine->handle();
1148 return -1;
1149}
1150
1151/*!
1152 \enum QFile::MemoryMapFlags
1153 \since 4.4
1154
1155 This enum describes special options that may be used by the map()
1156 function.
1157
1158 \value NoOptions No options.
1159*/
1160
1161/*!
1162 \since 4.4
1163 Maps \a size bytes of the file into memory starting at \a offset. A file
1164 should be open for a map to succeed but the file does not need to stay
1165 open after the memory has been mapped. When the QFile is destroyed
1166 or a new file is opened with this object, any maps that have not been
1167 unmapped will automatically be unmapped.
1168
1169 Any mapping options can be passed through \a flags.
1170
1171 Returns a pointer to the memory or 0 if there is an error.
1172
1173 \note On Windows CE 5.0 the file will be closed before mapping occurs.
1174
1175 \sa unmap(), QAbstractFileEngine::supportsExtension()
1176 */
1177uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags)
1178{
1179 Q_D(QFile);
1180 QAbstractFileEngine *engine = fileEngine();
1181 if (engine
1182 && engine->supportsExtension(QAbstractFileEngine::MapExtension)) {
1183 unsetError();
1184 uchar *address = engine->map(offset, size, flags);
1185 if (address == 0)
1186 d->setError(engine->error(), engine->errorString());
1187 return address;
1188 }
1189 return 0;
1190}
1191
1192/*!
1193 \since 4.4
1194 Unmaps the memory \a address.
1195
1196 Returns true if the unmap succeeds; false otherwise.
1197
1198 \sa map(), QAbstractFileEngine::supportsExtension()
1199 */
1200bool QFile::unmap(uchar *address)
1201{
1202 Q_D(QFile);
1203 QAbstractFileEngine *engine = fileEngine();
1204 if (engine
1205 && engine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
1206 unsetError();
1207 bool success = engine->unmap(address);
1208 if (!success)
1209 d->setError(engine->error(), engine->errorString());
1210 return success;
1211 }
1212 return false;
1213}
1214
1215/*!
1216 \fn QString QFile::name() const
1217
1218 Use fileName() instead.
1219*/
1220
1221/*!
1222 \fn void QFile::setName(const QString &name)
1223
1224 Use setFileName() instead.
1225*/
1226
1227/*!
1228 Sets the file size (in bytes) \a sz. Returns true if the file if the
1229 resize succeeds; false otherwise. If \a sz is larger than the file
1230 currently is the new bytes will be set to 0, if \a sz is smaller the
1231 file is simply truncated.
1232
1233 \sa size(), setFileName()
1234*/
1235
1236bool
1237QFile::resize(qint64 sz)
1238{
1239 Q_D(QFile);
1240 if (!d->ensureFlushed())
1241 return false;
1242 if (isOpen() && fileEngine()->pos() > sz)
1243 seek(sz);
1244 if(fileEngine()->setSize(sz)) {
1245 unsetError();
1246 return true;
1247 }
1248 d->setError(QFile::ResizeError, errno);
1249 return false;
1250}
1251
1252/*!
1253 \overload
1254
1255 Sets \a fileName to size (in bytes) \a sz. Returns true if the file if
1256 the resize succeeds; false otherwise. If \a sz is larger than \a
1257 fileName currently is the new bytes will be set to 0, if \a sz is
1258 smaller the file is simply truncated.
1259
1260 \sa resize()
1261*/
1262
1263bool
1264QFile::resize(const QString &fileName, qint64 sz)
1265{
1266 return QFile(fileName).resize(sz);
1267}
1268
1269/*!
1270 Returns the complete OR-ed together combination of
1271 QFile::Permission for the file.
1272
1273 \sa setPermissions(), setFileName()
1274*/
1275
1276QFile::Permissions
1277QFile::permissions() const
1278{
1279 QAbstractFileEngine::FileFlags perms = fileEngine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
1280 return QFile::Permissions((int)perms); //ewww
1281}
1282
1283/*!
1284 \overload
1285
1286 Returns the complete OR-ed together combination of
1287 QFile::Permission for \a fileName.
1288*/
1289
1290QFile::Permissions
1291QFile::permissions(const QString &fileName)
1292{
1293 return QFile(fileName).permissions();
1294}
1295
1296/*!
1297 Sets the permissions for the file to the \a permissions specified.
1298 Returns true if successful, or false if the permissions cannot be
1299 modified.
1300
1301 \sa permissions(), setFileName()
1302*/
1303
1304bool
1305QFile::setPermissions(Permissions permissions)
1306{
1307 Q_D(QFile);
1308 if(fileEngine()->setPermissions(permissions)) {
1309 unsetError();
1310 return true;
1311 }
1312 d->setError(QFile::PermissionsError, errno);
1313 return false;
1314}
1315
1316/*!
1317 \overload
1318
1319 Sets the permissions for \a fileName file to \a permissions.
1320*/
1321
1322bool
1323QFile::setPermissions(const QString &fileName, Permissions permissions)
1324{
1325 return QFile(fileName).setPermissions(permissions);
1326}
1327
1328static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
1329{
1330 qint64 ret = engine->write(buffer->readPointer(), buffer->size());
1331 if (ret > 0)
1332 buffer->free(ret);
1333 return ret;
1334}
1335
1336/*!
1337 Flushes any buffered data to the file. Returns true if successful;
1338 otherwise returns false.
1339*/
1340
1341bool
1342QFile::flush()
1343{
1344 Q_D(QFile);
1345 if (!d->writeBuffer.isEmpty()) {
1346 qint64 size = d->writeBuffer.size();
1347 if (_qfile_writeData(d->fileEngine ? d->fileEngine : fileEngine(),
1348 &d->writeBuffer) != size) {
1349 QFile::FileError err = fileEngine()->error();
1350 if(err == QFile::UnspecifiedError)
1351 err = QFile::WriteError;
1352 d->setError(err, fileEngine()->errorString());
1353 return false;
1354 }
1355 }
1356
1357 if (!fileEngine()->flush()) {
1358 QFile::FileError err = fileEngine()->error();
1359 if(err == QFile::UnspecifiedError)
1360 err = QFile::WriteError;
1361 d->setError(err, fileEngine()->errorString());
1362 return false;
1363 }
1364 return true;
1365}
1366
1367/*!
1368 Flushes the file and then closes it.
1369
1370 \sa QIODevice::close()
1371*/
1372void
1373QFile::close()
1374{
1375 Q_D(QFile);
1376 if(!isOpen())
1377 return;
1378 flush();
1379 QIODevice::close();
1380
1381 unsetError();
1382 if(!fileEngine()->close())
1383 d->setError(fileEngine()->error(), fileEngine()->errorString());
1384}
1385
1386/*!
1387 Returns the size of the file.
1388
1389 For regular empty files on Unix (e.g. those in \c /proc), this function
1390 returns 0; the contents of such a file are generated on demand in response
1391 to you calling read().
1392*/
1393
1394qint64 QFile::size() const
1395{
1396 Q_D(const QFile);
1397 if (!d->ensureFlushed())
1398 return 0;
1399 return fileEngine()->size();
1400}
1401
1402/*!
1403 \reimp
1404*/
1405
1406qint64 QFile::pos() const
1407{
1408 return QIODevice::pos();
1409}
1410
1411/*!
1412 Returns true if the end of the file has been reached; otherwise returns
1413 false.
1414
1415 For regular empty files on Unix (e.g. those in \c /proc), this function
1416 returns true, since the file system reports that the size of such a file is
1417 0. Therefore, you should not depend on atEnd() when reading data from such a
1418 file, but rather call read() until no more data can be read.
1419*/
1420
1421bool QFile::atEnd() const
1422{
1423 Q_D(const QFile);
1424
1425 if (!isOpen())
1426 return true;
1427
1428 if (!d->ensureFlushed())
1429 return false;
1430
1431 // If there's buffered data left, we're not at the end.
1432 if (!d->buffer.isEmpty())
1433 return false;
1434
1435 // If the file engine knows best, say what it says.
1436 if (fileEngine()->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
1437 // Check if the file engine supports AtEndExtension, and if it does,
1438 // check if the file engine claims to be at the end.
1439 return fileEngine()->atEnd();
1440 }
1441
1442 // Fall back to checking how much is available (will stat files).
1443 return bytesAvailable() == 0;
1444}
1445
1446/*!
1447 \reimp
1448*/
1449
1450bool QFile::seek(qint64 off)
1451{
1452 Q_D(QFile);
1453 if (!isOpen()) {
1454 qWarning("QFile::seek: IODevice is not open");
1455 return false;
1456 }
1457
1458 if (!d->ensureFlushed())
1459 return false;
1460
1461 if (!fileEngine()->seek(off) || !QIODevice::seek(off)) {
1462 QFile::FileError err = fileEngine()->error();
1463 if(err == QFile::UnspecifiedError)
1464 err = QFile::PositionError;
1465 d->setError(err, fileEngine()->errorString());
1466 return false;
1467 }
1468 d->error = NoError;
1469 return true;
1470}
1471
1472/*!
1473 \reimp
1474*/
1475qint64 QFile::readLineData(char *data, qint64 maxlen)
1476{
1477 Q_D(QFile);
1478 if (!d->ensureFlushed())
1479 return -1;
1480
1481 if (fileEngine()->supportsExtension(QAbstractFileEngine::FastReadLineExtension))
1482 return fileEngine()->readLine(data, maxlen);
1483
1484 // Fall back to QIODevice's readLine implementation if the engine
1485 // cannot do it faster.
1486 return QIODevice::readLineData(data, maxlen);
1487}
1488
1489/*!
1490 \reimp
1491*/
1492
1493qint64 QFile::readData(char *data, qint64 len)
1494{
1495 Q_D(QFile);
1496 d->error = NoError;
1497 if (!d->ensureFlushed())
1498 return -1;
1499
1500 qint64 ret = -1;
1501 qint64 read = fileEngine()->read(data, len);
1502 if (read != -1)
1503 ret = read;
1504
1505 if(ret < 0) {
1506 QFile::FileError err = fileEngine()->error();
1507 if(err == QFile::UnspecifiedError)
1508 err = QFile::ReadError;
1509 d->setError(err, fileEngine()->errorString());
1510 }
1511 return ret;
1512}
1513
1514/*!
1515 \internal
1516*/
1517bool QFilePrivate::putCharHelper(char c)
1518{
1519#ifdef QT_NO_QOBJECT
1520 return QIODevicePrivate::putCharHelper(c);
1521#else
1522
1523 // Cutoff for code that doesn't only touch the buffer.
1524 int writeBufferSize = writeBuffer.size();
1525 if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
1526#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
1527 || ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
1528#endif
1529 ) {
1530 return QIODevicePrivate::putCharHelper(c);
1531 }
1532
1533 if (!(openMode & QIODevice::WriteOnly)) {
1534 if (openMode == QIODevice::NotOpen)
1535 qWarning("QIODevice::putChar: Closed device");
1536 else
1537 qWarning("QIODevice::putChar: ReadOnly device");
1538 return false;
1539 }
1540
1541 // Make sure the device is positioned correctly.
1542 const bool sequential = isSequential();
1543 if (pos != devicePos && !sequential && !q_func()->seek(pos))
1544 return false;
1545
1546 lastWasWrite = true;
1547
1548 int len = 1;
1549#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
1550 if ((openMode & QIODevice::Text) && c == '\n') {
1551 ++len;
1552 *writeBuffer.reserve(1) = '\r';
1553 }
1554#endif
1555
1556 // Write to buffer.
1557 *writeBuffer.reserve(1) = c;
1558
1559 if (!sequential) {
1560 pos += len;
1561 devicePos += len;
1562 if (!buffer.isEmpty())
1563 buffer.skip(len);
1564 }
1565
1566 return true;
1567#endif
1568}
1569
1570/*!
1571 \reimp
1572*/
1573
1574qint64
1575QFile::writeData(const char *data, qint64 len)
1576{
1577 Q_D(QFile);
1578 d->error = NoError;
1579 d->lastWasWrite = true;
1580 bool buffered = !(d->openMode & Unbuffered);
1581
1582 // Flush buffered data if this read will overflow.
1583 if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
1584 if (!flush())
1585 return -1;
1586 }
1587
1588 // Write directly to the engine if the block size is larger than
1589 // the write buffer size.
1590 if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
1591 QAbstractFileEngine *fe = d->fileEngine ? d->fileEngine : fileEngine();
1592 qint64 ret = fe->write(data, len);
1593 if(ret < 0) {
1594 QFile::FileError err = fileEngine()->error();
1595 if(err == QFile::UnspecifiedError)
1596 err = QFile::WriteError;
1597 d->setError(err, fileEngine()->errorString());
1598 }
1599 return ret;
1600 }
1601
1602 // Write to the buffer.
1603 char *writePointer = d->writeBuffer.reserve(len);
1604 if (len == 1)
1605 *writePointer = *data;
1606 else
1607 ::memcpy(writePointer, data, len);
1608 return len;
1609}
1610
1611/*!
1612 \internal
1613 Returns the QIOEngine for this QFile object.
1614*/
1615QAbstractFileEngine *QFile::fileEngine() const
1616{
1617 Q_D(const QFile);
1618 if(!d->fileEngine)
1619 d->fileEngine = QAbstractFileEngine::create(d->fileName);
1620 return d->fileEngine;
1621}
1622
1623/*!
1624 Returns the file error status.
1625
1626 The I/O device status returns an error code. For example, if open()
1627 returns false, or a read/write operation returns -1, this function can
1628 be called to find out the reason why the operation failed.
1629
1630 \sa unsetError()
1631*/
1632
1633QFile::FileError
1634QFile::error() const
1635{
1636 Q_D(const QFile);
1637 return d->error;
1638}
1639
1640/*!
1641 Sets the file's error to QFile::NoError.
1642
1643 \sa error()
1644*/
1645void
1646QFile::unsetError()
1647{
1648 Q_D(QFile);
1649 d->setError(QFile::NoError);
1650}
1651
1652QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.