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

Last change on this file since 780 was 769, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

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