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

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

corelib: QFile::copy(): Use DosCopy() instead of read/write. This also fixes errors with backup file creation in designer.

File size: 44.5 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 // ### note: if out is a QTemporaryFile instance, rename()
900 // below will fail on some platforms (such as OS/2) because
901 // the file will remain open for writing even after close()
902 if (!error && !out.rename(newName)) {
903 error = true;
904 d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName));
905 }
906#ifdef QT_NO_TEMPORARYFILE
907 if (error)
908 out.remove();
909#else
910 if (!error)
911 out.setAutoRemove(false);
912#endif
913 }
914 }
915 if(!error) {
916 QFile::setPermissions(newName, permissions());
917 unsetError();
918 return true;
919 }
920 }
921 }
922 return false;
923}
924
925/*!
926 \overload
927
928 Copies the file \a fileName to \a newName. Returns true if successful;
929 otherwise returns false.
930
931 If a file with the name \a newName already exists, copy() returns false
932 (i.e., QFile will not overwrite it).
933
934 \sa rename()
935*/
936
937bool
938QFile::copy(const QString &fileName, const QString &newName)
939{
940 return QFile(fileName).copy(newName);
941}
942
943/*!
944 Returns true if the file can only be manipulated sequentially;
945 otherwise returns false.
946
947 Most files support random-access, but some special files may not.
948
949 \sa QIODevice::isSequential()
950*/
951bool QFile::isSequential() const
952{
953 Q_D(const QFile);
954 return d->fileEngine && d->fileEngine->isSequential();
955}
956
957/*!
958 Opens the file using OpenMode \a mode, returning true if successful;
959 otherwise false.
960
961 The \a mode must be QIODevice::ReadOnly, QIODevice::WriteOnly, or
962 QIODevice::ReadWrite. It may also have additional flags, such as
963 QIODevice::Text and QIODevice::Unbuffered.
964
965 \note In \l{QIODevice::}{WriteOnly} or \l{QIODevice::}{ReadWrite}
966 mode, if the relevant file does not already exist, this function
967 will try to create a new file before opening it.
968
969 \note Because of limitations in the native API, QFile ignores the
970 Unbuffered flag on Windows.
971
972 \sa QIODevice::OpenMode, setFileName()
973*/
974bool QFile::open(OpenMode mode)
975{
976 Q_D(QFile);
977 if (isOpen()) {
978 qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
979 return false;
980 }
981 if (mode & Append)
982 mode |= WriteOnly;
983
984 unsetError();
985 if ((mode & (ReadOnly | WriteOnly)) == 0) {
986 qWarning("QIODevice::open: File access not specified");
987 return false;
988 }
989 if (fileEngine()->open(mode)) {
990 QIODevice::open(mode);
991 if (mode & Append)
992 seek(size());
993 return true;
994 }
995 QFile::FileError err = fileEngine()->error();
996 if(err == QFile::UnspecifiedError)
997 err = QFile::OpenError;
998 d->setError(err, fileEngine()->errorString());
999 return false;
1000}
1001
1002/*! \fn QFile::open(OpenMode, FILE*)
1003
1004 Use open(FILE *, OpenMode) instead.
1005*/
1006
1007/*!
1008 \overload
1009
1010 Opens the existing file handle \a fh in the given \a mode.
1011 Returns true if successful; otherwise returns false.
1012
1013 Example:
1014 \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 3
1015
1016 When a QFile is opened using this function, close() does not actually
1017 close the file, but only flushes it.
1018
1019 \bold{Warning:}
1020 \list 1
1021 \o If \a fh is \c stdin, \c stdout, or \c stderr, you may not be able
1022 to seek(). See QIODevice::isSequentialAccess() for more information.
1023 \o Since this function opens the file without specifying the file name,
1024 you cannot use this QFile with a QFileInfo.
1025 \endlist
1026
1027 \note For Windows CE you may not be able to call seek() and resize().
1028 Also, size() is set to \c 0.
1029
1030 \sa close(), {qmake Variable Reference#CONFIG}{qmake Variable Reference}
1031
1032 \bold{Note for the Windows Platform}
1033
1034 \a fh must be opened in binary mode (i.e., the mode string must contain
1035 'b', as in "rb" or "wb") when accessing files and other random-access
1036 devices. Qt will translate the end-of-line characters if you pass
1037 QIODevice::Text to \a mode. Sequential devices, such as stdin and stdout,
1038 are unaffected by this limitation.
1039
1040 You need to enable support for console applications in order to use the
1041 stdin, stdout and stderr streams at the console. To do this, add the
1042 following declaration to your application's project file:
1043
1044 \snippet doc/src/snippets/code/src_corelib_io_qfile.cpp 4
1045*/
1046bool QFile::open(FILE *fh, OpenMode mode)
1047{
1048 Q_D(QFile);
1049 if (isOpen()) {
1050 qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
1051 return false;
1052 }
1053 if (mode & Append)
1054 mode |= WriteOnly;
1055 unsetError();
1056 if ((mode & (ReadOnly | WriteOnly)) == 0) {
1057 qWarning("QFile::open: File access not specified");
1058 return false;
1059 }
1060 if(d->openExternalFile(mode, fh)) {
1061 QIODevice::open(mode);
1062 if (mode & Append) {
1063 seek(size());
1064 } else {
1065 long pos = ftell(fh);
1066 if (pos != -1)
1067 seek(pos);
1068 }
1069 return true;
1070 }
1071 return false;
1072}
1073
1074/*! \fn QFile::open(OpenMode, int)
1075
1076 Use open(int, OpenMode) instead.
1077*/
1078
1079/*!
1080 \overload
1081
1082 Opens the existing file descripter \a fd in the given \a mode.
1083 Returns true if successful; otherwise returns false.
1084
1085 When a QFile is opened using this function, close() does not
1086 actually close the file.
1087
1088 The QFile that is opened using this function is automatically set
1089 to be in raw mode; this means that the file input/output functions
1090 are slow. If you run into performance issues, you should try to
1091 use one of the other open functions.
1092
1093 \warning If \a fd is 0 (\c stdin), 1 (\c stdout), or 2 (\c
1094 stderr), you may not be able to seek(). size() is set to \c
1095 LLONG_MAX (in \c <climits>).
1096
1097 \warning For Windows CE you may not be able to call seek(), setSize(),
1098 fileTime(). size() is set to \c 0.
1099
1100 \warning Since this function opens the file without specifying the file name,
1101 you cannot use this QFile with a QFileInfo.
1102
1103 \sa close()
1104*/
1105bool QFile::open(int fd, OpenMode mode)
1106{
1107 Q_D(QFile);
1108 if (isOpen()) {
1109 qWarning("QFile::open: File (%s) already open", qPrintable(fileName()));
1110 return false;
1111 }
1112 if (mode & Append)
1113 mode |= WriteOnly;
1114 unsetError();
1115 if ((mode & (ReadOnly | WriteOnly)) == 0) {
1116 qWarning("QFile::open: File access not specified");
1117 return false;
1118 }
1119 if(d->openExternalFile(mode, fd)) {
1120 QIODevice::open(mode);
1121 if (mode & Append)
1122 seek(size());
1123 return true;
1124 }
1125 return false;
1126}
1127
1128/*!
1129 Returns the file handle of the file.
1130
1131 This is a small positive integer, suitable for use with C library
1132 functions such as fdopen() and fcntl(). On systems that use file
1133 descriptors for sockets (i.e. Unix systems, but not Windows) the handle
1134 can be used with QSocketNotifier as well.
1135
1136 If the file is not open, or there is an error, handle() returns -1.
1137
1138 This function is not supported on Windows CE.
1139
1140 \sa QSocketNotifier
1141*/
1142
1143int
1144QFile::handle() const
1145{
1146 if (!isOpen())
1147 return -1;
1148
1149 if (QAbstractFileEngine *engine = fileEngine())
1150 return engine->handle();
1151 return -1;
1152}
1153
1154/*!
1155 \enum QFile::MemoryMapFlags
1156 \since 4.4
1157
1158 This enum describes special options that may be used by the map()
1159 function.
1160
1161 \value NoOptions No options.
1162*/
1163
1164/*!
1165 \since 4.4
1166 Maps \a size bytes of the file into memory starting at \a offset. A file
1167 should be open for a map to succeed but the file does not need to stay
1168 open after the memory has been mapped. When the QFile is destroyed
1169 or a new file is opened with this object, any maps that have not been
1170 unmapped will automatically be unmapped.
1171
1172 Any mapping options can be passed through \a flags.
1173
1174 Returns a pointer to the memory or 0 if there is an error.
1175
1176 \note On Windows CE 5.0 the file will be closed before mapping occurs.
1177
1178 \sa unmap(), QAbstractFileEngine::supportsExtension()
1179 */
1180uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags)
1181{
1182 Q_D(QFile);
1183 QAbstractFileEngine *engine = fileEngine();
1184 if (engine
1185 && engine->supportsExtension(QAbstractFileEngine::MapExtension)) {
1186 unsetError();
1187 uchar *address = engine->map(offset, size, flags);
1188 if (address == 0)
1189 d->setError(engine->error(), engine->errorString());
1190 return address;
1191 }
1192 return 0;
1193}
1194
1195/*!
1196 \since 4.4
1197 Unmaps the memory \a address.
1198
1199 Returns true if the unmap succeeds; false otherwise.
1200
1201 \sa map(), QAbstractFileEngine::supportsExtension()
1202 */
1203bool QFile::unmap(uchar *address)
1204{
1205 Q_D(QFile);
1206 QAbstractFileEngine *engine = fileEngine();
1207 if (engine
1208 && engine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
1209 unsetError();
1210 bool success = engine->unmap(address);
1211 if (!success)
1212 d->setError(engine->error(), engine->errorString());
1213 return success;
1214 }
1215 return false;
1216}
1217
1218/*!
1219 \fn QString QFile::name() const
1220
1221 Use fileName() instead.
1222*/
1223
1224/*!
1225 \fn void QFile::setName(const QString &name)
1226
1227 Use setFileName() instead.
1228*/
1229
1230/*!
1231 Sets the file size (in bytes) \a sz. Returns true if the file if the
1232 resize succeeds; false otherwise. If \a sz is larger than the file
1233 currently is the new bytes will be set to 0, if \a sz is smaller the
1234 file is simply truncated.
1235
1236 \sa size(), setFileName()
1237*/
1238
1239bool
1240QFile::resize(qint64 sz)
1241{
1242 Q_D(QFile);
1243 if (!d->ensureFlushed())
1244 return false;
1245 if (isOpen() && fileEngine()->pos() > sz)
1246 seek(sz);
1247 if(fileEngine()->setSize(sz)) {
1248 unsetError();
1249 return true;
1250 }
1251 d->setError(QFile::ResizeError, errno);
1252 return false;
1253}
1254
1255/*!
1256 \overload
1257
1258 Sets \a fileName to size (in bytes) \a sz. Returns true if the file if
1259 the resize succeeds; false otherwise. If \a sz is larger than \a
1260 fileName currently is the new bytes will be set to 0, if \a sz is
1261 smaller the file is simply truncated.
1262
1263 \sa resize()
1264*/
1265
1266bool
1267QFile::resize(const QString &fileName, qint64 sz)
1268{
1269 return QFile(fileName).resize(sz);
1270}
1271
1272/*!
1273 Returns the complete OR-ed together combination of
1274 QFile::Permission for the file.
1275
1276 \sa setPermissions(), setFileName()
1277*/
1278
1279QFile::Permissions
1280QFile::permissions() const
1281{
1282 QAbstractFileEngine::FileFlags perms = fileEngine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
1283 return QFile::Permissions((int)perms); //ewww
1284}
1285
1286/*!
1287 \overload
1288
1289 Returns the complete OR-ed together combination of
1290 QFile::Permission for \a fileName.
1291*/
1292
1293QFile::Permissions
1294QFile::permissions(const QString &fileName)
1295{
1296 return QFile(fileName).permissions();
1297}
1298
1299/*!
1300 Sets the permissions for the file to the \a permissions specified.
1301 Returns true if successful, or false if the permissions cannot be
1302 modified.
1303
1304 \sa permissions(), setFileName()
1305*/
1306
1307bool
1308QFile::setPermissions(Permissions permissions)
1309{
1310 Q_D(QFile);
1311 if(fileEngine()->setPermissions(permissions)) {
1312 unsetError();
1313 return true;
1314 }
1315 d->setError(QFile::PermissionsError, errno);
1316 return false;
1317}
1318
1319/*!
1320 \overload
1321
1322 Sets the permissions for \a fileName file to \a permissions.
1323*/
1324
1325bool
1326QFile::setPermissions(const QString &fileName, Permissions permissions)
1327{
1328 return QFile(fileName).setPermissions(permissions);
1329}
1330
1331static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
1332{
1333 qint64 ret = engine->write(buffer->readPointer(), buffer->size());
1334 if (ret > 0)
1335 buffer->free(ret);
1336 return ret;
1337}
1338
1339/*!
1340 Flushes any buffered data to the file. Returns true if successful;
1341 otherwise returns false.
1342*/
1343
1344bool
1345QFile::flush()
1346{
1347 Q_D(QFile);
1348 if (!d->writeBuffer.isEmpty()) {
1349 qint64 size = d->writeBuffer.size();
1350 if (_qfile_writeData(d->fileEngine ? d->fileEngine : fileEngine(),
1351 &d->writeBuffer) != size) {
1352 QFile::FileError err = fileEngine()->error();
1353 if(err == QFile::UnspecifiedError)
1354 err = QFile::WriteError;
1355 d->setError(err, fileEngine()->errorString());
1356 return false;
1357 }
1358 }
1359
1360 if (!fileEngine()->flush()) {
1361 QFile::FileError err = fileEngine()->error();
1362 if(err == QFile::UnspecifiedError)
1363 err = QFile::WriteError;
1364 d->setError(err, fileEngine()->errorString());
1365 return false;
1366 }
1367 return true;
1368}
1369
1370/*!
1371 Flushes the file and then closes it.
1372
1373 \sa QIODevice::close()
1374*/
1375void
1376QFile::close()
1377{
1378 Q_D(QFile);
1379 if(!isOpen())
1380 return;
1381 flush();
1382 QIODevice::close();
1383
1384 unsetError();
1385 if(!fileEngine()->close())
1386 d->setError(fileEngine()->error(), fileEngine()->errorString());
1387}
1388
1389/*!
1390 Returns the size of the file.
1391
1392 For regular empty files on Unix (e.g. those in \c /proc), this function
1393 returns 0; the contents of such a file are generated on demand in response
1394 to you calling read().
1395*/
1396
1397qint64 QFile::size() const
1398{
1399 Q_D(const QFile);
1400 if (!d->ensureFlushed())
1401 return 0;
1402 return fileEngine()->size();
1403}
1404
1405/*!
1406 \reimp
1407*/
1408
1409qint64 QFile::pos() const
1410{
1411 return QIODevice::pos();
1412}
1413
1414/*!
1415 Returns true if the end of the file has been reached; otherwise returns
1416 false.
1417
1418 For regular empty files on Unix (e.g. those in \c /proc), this function
1419 returns true, since the file system reports that the size of such a file is
1420 0. Therefore, you should not depend on atEnd() when reading data from such a
1421 file, but rather call read() until no more data can be read.
1422*/
1423
1424bool QFile::atEnd() const
1425{
1426 Q_D(const QFile);
1427
1428 if (!isOpen())
1429 return true;
1430
1431 if (!d->ensureFlushed())
1432 return false;
1433
1434 // If there's buffered data left, we're not at the end.
1435 if (!d->buffer.isEmpty())
1436 return false;
1437
1438 // If the file engine knows best, say what it says.
1439 if (fileEngine()->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
1440 // Check if the file engine supports AtEndExtension, and if it does,
1441 // check if the file engine claims to be at the end.
1442 return fileEngine()->atEnd();
1443 }
1444
1445 // Fall back to checking how much is available (will stat files).
1446 return bytesAvailable() == 0;
1447}
1448
1449/*!
1450 \reimp
1451*/
1452
1453bool QFile::seek(qint64 off)
1454{
1455 Q_D(QFile);
1456 if (!isOpen()) {
1457 qWarning("QFile::seek: IODevice is not open");
1458 return false;
1459 }
1460
1461 if (!d->ensureFlushed())
1462 return false;
1463
1464 if (!fileEngine()->seek(off) || !QIODevice::seek(off)) {
1465 QFile::FileError err = fileEngine()->error();
1466 if(err == QFile::UnspecifiedError)
1467 err = QFile::PositionError;
1468 d->setError(err, fileEngine()->errorString());
1469 return false;
1470 }
1471 d->error = NoError;
1472 return true;
1473}
1474
1475/*!
1476 \reimp
1477*/
1478qint64 QFile::readLineData(char *data, qint64 maxlen)
1479{
1480 Q_D(QFile);
1481 if (!d->ensureFlushed())
1482 return -1;
1483
1484 if (fileEngine()->supportsExtension(QAbstractFileEngine::FastReadLineExtension))
1485 return fileEngine()->readLine(data, maxlen);
1486
1487 // Fall back to QIODevice's readLine implementation if the engine
1488 // cannot do it faster.
1489 return QIODevice::readLineData(data, maxlen);
1490}
1491
1492/*!
1493 \reimp
1494*/
1495
1496qint64 QFile::readData(char *data, qint64 len)
1497{
1498 Q_D(QFile);
1499 d->error = NoError;
1500 if (!d->ensureFlushed())
1501 return -1;
1502
1503 qint64 ret = -1;
1504 qint64 read = fileEngine()->read(data, len);
1505 if (read != -1)
1506 ret = read;
1507
1508 if(ret < 0) {
1509 QFile::FileError err = fileEngine()->error();
1510 if(err == QFile::UnspecifiedError)
1511 err = QFile::ReadError;
1512 d->setError(err, fileEngine()->errorString());
1513 }
1514 return ret;
1515}
1516
1517/*!
1518 \internal
1519*/
1520bool QFilePrivate::putCharHelper(char c)
1521{
1522#ifdef QT_NO_QOBJECT
1523 return QIODevicePrivate::putCharHelper(c);
1524#else
1525
1526 // Cutoff for code that doesn't only touch the buffer.
1527 int writeBufferSize = writeBuffer.size();
1528 if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
1529#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
1530 || ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
1531#endif
1532 ) {
1533 return QIODevicePrivate::putCharHelper(c);
1534 }
1535
1536 if (!(openMode & QIODevice::WriteOnly)) {
1537 if (openMode == QIODevice::NotOpen)
1538 qWarning("QIODevice::putChar: Closed device");
1539 else
1540 qWarning("QIODevice::putChar: ReadOnly device");
1541 return false;
1542 }
1543
1544 // Make sure the device is positioned correctly.
1545 const bool sequential = isSequential();
1546 if (pos != devicePos && !sequential && !q_func()->seek(pos))
1547 return false;
1548
1549 lastWasWrite = true;
1550
1551 int len = 1;
1552#if defined(Q_OS_WIN) || defined(Q_OS_OS2)
1553 if ((openMode & QIODevice::Text) && c == '\n') {
1554 ++len;
1555 *writeBuffer.reserve(1) = '\r';
1556 }
1557#endif
1558
1559 // Write to buffer.
1560 *writeBuffer.reserve(1) = c;
1561
1562 if (!sequential) {
1563 pos += len;
1564 devicePos += len;
1565 if (!buffer.isEmpty())
1566 buffer.skip(len);
1567 }
1568
1569 return true;
1570#endif
1571}
1572
1573/*!
1574 \reimp
1575*/
1576
1577qint64
1578QFile::writeData(const char *data, qint64 len)
1579{
1580 Q_D(QFile);
1581 d->error = NoError;
1582 d->lastWasWrite = true;
1583 bool buffered = !(d->openMode & Unbuffered);
1584
1585 // Flush buffered data if this read will overflow.
1586 if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
1587 if (!flush())
1588 return -1;
1589 }
1590
1591 // Write directly to the engine if the block size is larger than
1592 // the write buffer size.
1593 if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
1594 QAbstractFileEngine *fe = d->fileEngine ? d->fileEngine : fileEngine();
1595 qint64 ret = fe->write(data, len);
1596 if(ret < 0) {
1597 QFile::FileError err = fileEngine()->error();
1598 if(err == QFile::UnspecifiedError)
1599 err = QFile::WriteError;
1600 d->setError(err, fileEngine()->errorString());
1601 }
1602 return ret;
1603 }
1604
1605 // Write to the buffer.
1606 char *writePointer = d->writeBuffer.reserve(len);
1607 if (len == 1)
1608 *writePointer = *data;
1609 else
1610 ::memcpy(writePointer, data, len);
1611 return len;
1612}
1613
1614/*!
1615 \internal
1616 Returns the QIOEngine for this QFile object.
1617*/
1618QAbstractFileEngine *QFile::fileEngine() const
1619{
1620 Q_D(const QFile);
1621 if(!d->fileEngine)
1622 d->fileEngine = QAbstractFileEngine::create(d->fileName);
1623 return d->fileEngine;
1624}
1625
1626/*!
1627 Returns the file error status.
1628
1629 The I/O device status returns an error code. For example, if open()
1630 returns false, or a read/write operation returns -1, this function can
1631 be called to find out the reason why the operation failed.
1632
1633 \sa unsetError()
1634*/
1635
1636QFile::FileError
1637QFile::error() const
1638{
1639 Q_D(const QFile);
1640 return d->error;
1641}
1642
1643/*!
1644 Sets the file's error to QFile::NoError.
1645
1646 \sa error()
1647*/
1648void
1649QFile::unsetError()
1650{
1651 Q_D(QFile);
1652 d->setError(QFile::NoError);
1653}
1654
1655QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.