Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/io/qfile.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||
---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||
2 | ** | - | ||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||
5 | ** | - | ||||||
6 | ** This file is part of the QtCore module of the Qt Toolkit. | - | ||||||
7 | ** | - | ||||||
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||
9 | ** Commercial License Usage | - | ||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||
15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||
16 | ** | - | ||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||
19 | ** General Public License version 3 as published by the Free Software | - | ||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||
24 | ** | - | ||||||
25 | ** GNU General Public License Usage | - | ||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||
35 | ** | - | ||||||
36 | ** $QT_END_LICENSE$ | - | ||||||
37 | ** | - | ||||||
38 | ****************************************************************************/ | - | ||||||
39 | - | |||||||
40 | #include "qplatformdefs.h" | - | ||||||
41 | #include "qdebug.h" | - | ||||||
42 | #include "qfile.h" | - | ||||||
43 | #include "qfsfileengine_p.h" | - | ||||||
44 | #include "qtemporaryfile.h" | - | ||||||
45 | #include "qlist.h" | - | ||||||
46 | #include "qfileinfo.h" | - | ||||||
47 | #include "private/qiodevice_p.h" | - | ||||||
48 | #include "private/qfile_p.h" | - | ||||||
49 | #include "private/qfilesystemengine_p.h" | - | ||||||
50 | #include "private/qsystemerror_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 | - | |||||||
59 | QT_BEGIN_NAMESPACE | - | ||||||
60 | - | |||||||
61 | //************* QFilePrivate | - | ||||||
62 | QFilePrivate::QFilePrivate() | - | ||||||
63 | { | - | ||||||
64 | } | - | ||||||
65 | - | |||||||
66 | QFilePrivate::~QFilePrivate() | - | ||||||
67 | { | - | ||||||
68 | } | - | ||||||
69 | - | |||||||
70 | bool | - | ||||||
71 | QFilePrivate::openExternalFile(int flags, int fd, QFile::FileHandleFlags handleFlags) | - | ||||||
72 | { | - | ||||||
73 | #ifdef QT_NO_FSFILEENGINE | - | ||||||
74 | Q_UNUSED(flags); | - | ||||||
75 | Q_UNUSED(fd); | - | ||||||
76 | return false; | - | ||||||
77 | #else | - | ||||||
78 | delete fileEngine; | - | ||||||
79 | fileEngine = 0; | - | ||||||
80 | QFSFileEngine *fe = new QFSFileEngine; | - | ||||||
81 | fileEngine = fe; | - | ||||||
82 | return fe->open(QIODevice::OpenMode(flags), fd, handleFlags); | - | ||||||
83 | #endif | - | ||||||
84 | } | - | ||||||
85 | - | |||||||
86 | bool | - | ||||||
87 | QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handleFlags) | - | ||||||
88 | { | - | ||||||
89 | #ifdef QT_NO_FSFILEENGINE | - | ||||||
90 | Q_UNUSED(flags); | - | ||||||
91 | Q_UNUSED(fh); | - | ||||||
92 | return false; | - | ||||||
93 | #else | - | ||||||
94 | delete fileEngine; | - | ||||||
95 | fileEngine = 0; | - | ||||||
96 | QFSFileEngine *fe = new QFSFileEngine; | - | ||||||
97 | fileEngine = fe; | - | ||||||
98 | return fe->open(QIODevice::OpenMode(flags), fh, handleFlags); | - | ||||||
99 | #endif | - | ||||||
100 | } | - | ||||||
101 | - | |||||||
102 | QAbstractFileEngine *QFilePrivate::engine() const | - | ||||||
103 | { | - | ||||||
104 | if (!fileEngine) | - | ||||||
105 | fileEngine = QAbstractFileEngine::create(fileName); | - | ||||||
106 | return fileEngine; | - | ||||||
107 | } | - | ||||||
108 | - | |||||||
109 | //************* QFile | - | ||||||
110 | - | |||||||
111 | /*! | - | ||||||
112 | \class QFile | - | ||||||
113 | \inmodule QtCore | - | ||||||
114 | \brief The QFile class provides an interface for reading from and writing to files. | - | ||||||
115 | - | |||||||
116 | \ingroup io | - | ||||||
117 | - | |||||||
118 | \reentrant | - | ||||||
119 | - | |||||||
120 | QFile is an I/O device for reading and writing text and binary | - | ||||||
121 | files and \l{The Qt Resource System}{resources}. A QFile may be | - | ||||||
122 | used by itself or, more conveniently, with a QTextStream or | - | ||||||
123 | QDataStream. | - | ||||||
124 | - | |||||||
125 | The file name is usually passed in the constructor, but it can be | - | ||||||
126 | set at any time using setFileName(). QFile expects the file | - | ||||||
127 | separator to be '/' regardless of operating system. The use of | - | ||||||
128 | other separators (e.g., '\\') is not supported. | - | ||||||
129 | - | |||||||
130 | You can check for a file's existence using exists(), and remove a | - | ||||||
131 | file using remove(). (More advanced file system related operations | - | ||||||
132 | are provided by QFileInfo and QDir.) | - | ||||||
133 | - | |||||||
134 | The file is opened with open(), closed with close(), and flushed | - | ||||||
135 | with flush(). Data is usually read and written using QDataStream | - | ||||||
136 | or QTextStream, but you can also call the QIODevice-inherited | - | ||||||
137 | functions read(), readLine(), readAll(), write(). QFile also | - | ||||||
138 | inherits getChar(), putChar(), and ungetChar(), which work one | - | ||||||
139 | character at a time. | - | ||||||
140 | - | |||||||
141 | The size of the file is returned by size(). You can get the | - | ||||||
142 | current file position using pos(), or move to a new file position | - | ||||||
143 | using seek(). If you've reached the end of the file, atEnd() | - | ||||||
144 | returns \c true. | - | ||||||
145 | - | |||||||
146 | \section1 Reading Files Directly | - | ||||||
147 | - | |||||||
148 | The following example reads a text file line by line: | - | ||||||
149 | - | |||||||
150 | \snippet file/file.cpp 0 | - | ||||||
151 | - | |||||||
152 | The QIODevice::Text flag passed to open() tells Qt to convert | - | ||||||
153 | Windows-style line terminators ("\\r\\n") into C++-style | - | ||||||
154 | terminators ("\\n"). By default, QFile assumes binary, i.e. it | - | ||||||
155 | doesn't perform any conversion on the bytes stored in the file. | - | ||||||
156 | - | |||||||
157 | \section1 Using Streams to Read Files | - | ||||||
158 | - | |||||||
159 | The next example uses QTextStream to read a text file | - | ||||||
160 | line by line: | - | ||||||
161 | - | |||||||
162 | \snippet file/file.cpp 1 | - | ||||||
163 | - | |||||||
164 | QTextStream takes care of converting the 8-bit data stored on | - | ||||||
165 | disk into a 16-bit Unicode QString. By default, it assumes that | - | ||||||
166 | the user system's local 8-bit encoding is used (e.g., UTF-8 | - | ||||||
167 | on most unix based operating systems; see QTextCodec::codecForLocale() for | - | ||||||
168 | details). This can be changed using \l QTextStream::setCodec(). | - | ||||||
169 | - | |||||||
170 | To write text, we can use operator<<(), which is overloaded to | - | ||||||
171 | take a QTextStream on the left and various data types (including | - | ||||||
172 | QString) on the right: | - | ||||||
173 | - | |||||||
174 | \snippet file/file.cpp 2 | - | ||||||
175 | - | |||||||
176 | QDataStream is similar, in that you can use operator<<() to write | - | ||||||
177 | data and operator>>() to read it back. See the class | - | ||||||
178 | documentation for details. | - | ||||||
179 | - | |||||||
180 | When you use QFile, QFileInfo, and QDir to access the file system | - | ||||||
181 | with Qt, you can use Unicode file names. On Unix, these file | - | ||||||
182 | names are converted to an 8-bit encoding. If you want to use | - | ||||||
183 | standard C++ APIs (\c <cstdio> or \c <iostream>) or | - | ||||||
184 | platform-specific APIs to access files instead of QFile, you can | - | ||||||
185 | use the encodeName() and decodeName() functions to convert | - | ||||||
186 | between Unicode file names and 8-bit file names. | - | ||||||
187 | - | |||||||
188 | On Unix, there are some special system files (e.g. in \c /proc) for which | - | ||||||
189 | size() will always return 0, yet you may still be able to read more data | - | ||||||
190 | from such a file; the data is generated in direct response to you calling | - | ||||||
191 | read(). In this case, however, you cannot use atEnd() to determine if | - | ||||||
192 | there is more data to read (since atEnd() will return true for a file that | - | ||||||
193 | claims to have size 0). Instead, you should either call readAll(), or call | - | ||||||
194 | read() or readLine() repeatedly until no more data can be read. The next | - | ||||||
195 | example uses QTextStream to read \c /proc/modules line by line: | - | ||||||
196 | - | |||||||
197 | \snippet file/file.cpp 3 | - | ||||||
198 | - | |||||||
199 | \section1 Signals | - | ||||||
200 | - | |||||||
201 | Unlike other QIODevice implementations, such as QTcpSocket, QFile does not | - | ||||||
202 | emit the aboutToClose(), bytesWritten(), or readyRead() signals. This | - | ||||||
203 | implementation detail means that QFile is not suitable for reading and | - | ||||||
204 | writing certain types of files, such as device files on Unix platforms. | - | ||||||
205 | - | |||||||
206 | \section1 Platform Specific Issues | - | ||||||
207 | - | |||||||
208 | File permissions are handled differently on Unix-like systems and | - | ||||||
209 | Windows. In a non \l{QIODevice::isWritable()}{writable} | - | ||||||
210 | directory on Unix-like systems, files cannot be created. This is not always | - | ||||||
211 | the case on Windows, where, for instance, the 'My Documents' | - | ||||||
212 | directory usually is not writable, but it is still possible to | - | ||||||
213 | create files in it. | - | ||||||
214 | - | |||||||
215 | Qt's understanding of file permissions is limited, which affects especially | - | ||||||
216 | the \l QFile::setPermissions() function. On Windows, Qt will set only the | - | ||||||
217 | legacy read-only flag, and that only when none of the Write* flags are | - | ||||||
218 | passed. Qt does not manipulate access control lists (ACLs), which makes this | - | ||||||
219 | function mostly useless for NTFS volumes. It may still be of use for USB | - | ||||||
220 | sticks that use VFAT file systems. POSIX ACLs are not manipulated, either. | - | ||||||
221 | - | |||||||
222 | \sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System} | - | ||||||
223 | */ | - | ||||||
224 | - | |||||||
225 | #ifdef QT_NO_QOBJECT | - | ||||||
226 | QFile::QFile() | - | ||||||
227 | : QFileDevice(*new QFilePrivate) | - | ||||||
228 | { | - | ||||||
229 | } | - | ||||||
230 | QFile::QFile(const QString &name) | - | ||||||
231 | : QFileDevice(*new QFilePrivate) | - | ||||||
232 | { | - | ||||||
233 | d_func()->fileName = name; | - | ||||||
234 | } | - | ||||||
235 | QFile::QFile(QFilePrivate &dd) | - | ||||||
236 | : QFileDevice(dd) | - | ||||||
237 | { | - | ||||||
238 | } | - | ||||||
239 | #else | - | ||||||
240 | /*! | - | ||||||
241 | Constructs a QFile object. | - | ||||||
242 | */ | - | ||||||
243 | QFile::QFile() | - | ||||||
244 | : QFileDevice(*new QFilePrivate, 0) | - | ||||||
245 | { | - | ||||||
246 | } | - | ||||||
247 | /*! | - | ||||||
248 | Constructs a new file object with the given \a parent. | - | ||||||
249 | */ | - | ||||||
250 | QFile::QFile(QObject *parent) | - | ||||||
251 | : QFileDevice(*new QFilePrivate, parent) | - | ||||||
252 | { | - | ||||||
253 | } | - | ||||||
254 | /*! | - | ||||||
255 | Constructs a new file object to represent the file with the given \a name. | - | ||||||
256 | */ | - | ||||||
257 | QFile::QFile(const QString &name) | - | ||||||
258 | : QFileDevice(*new QFilePrivate, 0) | - | ||||||
259 | { | - | ||||||
260 | Q_D(QFile); | - | ||||||
261 | d->fileName = name; | - | ||||||
262 | } | - | ||||||
263 | /*! | - | ||||||
264 | Constructs a new file object with the given \a parent to represent the | - | ||||||
265 | file with the specified \a name. | - | ||||||
266 | */ | - | ||||||
267 | QFile::QFile(const QString &name, QObject *parent) | - | ||||||
268 | : QFileDevice(*new QFilePrivate, parent) | - | ||||||
269 | { | - | ||||||
270 | Q_D(QFile); | - | ||||||
271 | d->fileName = name; | - | ||||||
272 | } | - | ||||||
273 | /*! | - | ||||||
274 | \internal | - | ||||||
275 | */ | - | ||||||
276 | QFile::QFile(QFilePrivate &dd, QObject *parent) | - | ||||||
277 | : QFileDevice(dd, parent) | - | ||||||
278 | { | - | ||||||
279 | } | - | ||||||
280 | #endif | - | ||||||
281 | - | |||||||
282 | /*! | - | ||||||
283 | Destroys the file object, closing it if necessary. | - | ||||||
284 | */ | - | ||||||
285 | QFile::~QFile() | - | ||||||
286 | { | - | ||||||
287 | } | - | ||||||
288 | - | |||||||
289 | /*! | - | ||||||
290 | Returns the name set by setFileName() or to the QFile | - | ||||||
291 | constructors. | - | ||||||
292 | - | |||||||
293 | \sa setFileName(), QFileInfo::fileName() | - | ||||||
294 | */ | - | ||||||
295 | QString QFile::fileName() const | - | ||||||
296 | { | - | ||||||
297 | Q_D(const QFile); | - | ||||||
298 | return d->engine()->fileName(QAbstractFileEngine::DefaultName); | - | ||||||
299 | } | - | ||||||
300 | - | |||||||
301 | /*! | - | ||||||
302 | Sets the \a name of the file. The name can have no path, a | - | ||||||
303 | relative path, or an absolute path. | - | ||||||
304 | - | |||||||
305 | Do not call this function if the file has already been opened. | - | ||||||
306 | - | |||||||
307 | If the file name has no path or a relative path, the path used | - | ||||||
308 | will be the application's current directory path | - | ||||||
309 | \e{at the time of the open()} call. | - | ||||||
310 | - | |||||||
311 | Example: | - | ||||||
312 | \snippet code/src_corelib_io_qfile.cpp 0 | - | ||||||
313 | - | |||||||
314 | Note that the directory separator "/" works for all operating | - | ||||||
315 | systems supported by Qt. | - | ||||||
316 | - | |||||||
317 | \sa fileName(), QFileInfo, QDir | - | ||||||
318 | */ | - | ||||||
319 | void | - | ||||||
320 | QFile::setFileName(const QString &name) | - | ||||||
321 | { | - | ||||||
322 | Q_D(QFile); | - | ||||||
323 | if (isOpen()) { | - | ||||||
324 | qWarning("QFile::setFileName: File (%s) is already opened", | - | ||||||
325 | qPrintable(fileName())); | - | ||||||
326 | close(); | - | ||||||
327 | } | - | ||||||
328 | if(d->fileEngine) { //get a new file engine later | - | ||||||
329 | delete d->fileEngine; | - | ||||||
330 | d->fileEngine = 0; | - | ||||||
331 | } | - | ||||||
332 | d->fileName = name; | - | ||||||
333 | } | - | ||||||
334 | - | |||||||
335 | /*! | - | ||||||
336 | \fn QString QFile::decodeName(const char *localFileName) | - | ||||||
337 | - | |||||||
338 | \overload | - | ||||||
339 | - | |||||||
340 | Returns the Unicode version of the given \a localFileName. See | - | ||||||
341 | encodeName() for details. | - | ||||||
342 | */ | - | ||||||
343 | - | |||||||
344 | /*! | - | ||||||
345 | \fn QByteArray QFile::encodeName(const QString &fileName) | - | ||||||
346 | - | |||||||
347 | Converts \a fileName to the local 8-bit | - | ||||||
348 | encoding determined by the user's locale. This is sufficient for | - | ||||||
349 | file names that the user chooses. File names hard-coded into the | - | ||||||
350 | application should only use 7-bit ASCII filename characters. | - | ||||||
351 | - | |||||||
352 | \sa decodeName() | - | ||||||
353 | */ | - | ||||||
354 | - | |||||||
355 | /*! | - | ||||||
356 | \typedef QFile::EncoderFn | - | ||||||
357 | \obsolete | - | ||||||
358 | - | |||||||
359 | This is a typedef for a pointer to a function with the following | - | ||||||
360 | signature: | - | ||||||
361 | - | |||||||
362 | \snippet code/src_corelib_io_qfile.cpp 1 | - | ||||||
363 | - | |||||||
364 | \sa setEncodingFunction(), encodeName() | - | ||||||
365 | */ | - | ||||||
366 | - | |||||||
367 | /*! | - | ||||||
368 | \fn QString QFile::decodeName(const QByteArray &localFileName) | - | ||||||
369 | - | |||||||
370 | This does the reverse of QFile::encodeName() using \a localFileName. | - | ||||||
371 | - | |||||||
372 | \sa encodeName() | - | ||||||
373 | */ | - | ||||||
374 | - | |||||||
375 | /*! | - | ||||||
376 | \fn void QFile::setEncodingFunction(EncoderFn function) | - | ||||||
377 | \obsolete | - | ||||||
378 | - | |||||||
379 | This function does nothing. It is provided for compatibility with Qt 4 code | - | ||||||
380 | that attempted to set a different encoding function for file names. That | - | ||||||
381 | feature is flawed and no longer supported in Qt 5. | - | ||||||
382 | - | |||||||
383 | \sa encodeName(), setDecodingFunction() | - | ||||||
384 | */ | - | ||||||
385 | - | |||||||
386 | /*! | - | ||||||
387 | \typedef QFile::DecoderFn | - | ||||||
388 | - | |||||||
389 | This is a typedef for a pointer to a function with the following | - | ||||||
390 | signature: | - | ||||||
391 | - | |||||||
392 | \snippet code/src_corelib_io_qfile.cpp 2 | - | ||||||
393 | - | |||||||
394 | \sa setDecodingFunction() | - | ||||||
395 | */ | - | ||||||
396 | - | |||||||
397 | /*! | - | ||||||
398 | \fn void QFile::setDecodingFunction(DecoderFn function) | - | ||||||
399 | \obsolete | - | ||||||
400 | - | |||||||
401 | This function does nothing. It is provided for compatibility with Qt 4 code | - | ||||||
402 | that attempted to set a different decoding function for file names. That | - | ||||||
403 | feature is flawed and no longer supported in Qt 5. | - | ||||||
404 | - | |||||||
405 | \sa setEncodingFunction(), decodeName() | - | ||||||
406 | */ | - | ||||||
407 | - | |||||||
408 | /*! | - | ||||||
409 | \overload | - | ||||||
410 | - | |||||||
411 | Returns \c true if the file specified by fileName() exists; otherwise | - | ||||||
412 | returns \c false. | - | ||||||
413 | - | |||||||
414 | \sa fileName(), setFileName() | - | ||||||
415 | */ | - | ||||||
416 | - | |||||||
417 | bool | - | ||||||
418 | QFile::exists() const | - | ||||||
419 | { | - | ||||||
420 | Q_D(const QFile); | - | ||||||
421 | // 0x1000000 = QAbstractFileEngine::Refresh, forcing an update | - | ||||||
422 | return (d->engine()->fileFlags(QAbstractFileEngine::FlagsMask | - | ||||||
423 | | QAbstractFileEngine::FileFlag(0x1000000)) & QAbstractFileEngine::ExistsFlag); | - | ||||||
424 | } | - | ||||||
425 | - | |||||||
426 | /*! | - | ||||||
427 | Returns \c true if the file specified by \a fileName exists; otherwise | - | ||||||
428 | returns \c false. | - | ||||||
429 | - | |||||||
430 | \note If \a fileName is a symlink that points to a non-existing | - | ||||||
431 | file, false is returned. | - | ||||||
432 | */ | - | ||||||
433 | - | |||||||
434 | bool | - | ||||||
435 | QFile::exists(const QString &fileName) | - | ||||||
436 | { | - | ||||||
437 | return QFileInfo::exists(fileName); | - | ||||||
438 | } | - | ||||||
439 | - | |||||||
440 | /*! | - | ||||||
441 | \fn QString QFile::symLinkTarget() const | - | ||||||
442 | \since 4.2 | - | ||||||
443 | \overload | - | ||||||
444 | - | |||||||
445 | Returns the absolute path of the file or directory a symlink (or shortcut | - | ||||||
446 | on Windows) points to, or a an empty string if the object isn't a symbolic | - | ||||||
447 | link. | - | ||||||
448 | - | |||||||
449 | This name may not represent an existing file; it is only a string. | - | ||||||
450 | QFile::exists() returns \c true if the symlink points to an existing file. | - | ||||||
451 | - | |||||||
452 | \sa fileName(), setFileName() | - | ||||||
453 | */ | - | ||||||
454 | - | |||||||
455 | /*! | - | ||||||
456 | \obsolete | - | ||||||
457 | - | |||||||
458 | Use symLinkTarget() instead. | - | ||||||
459 | */ | - | ||||||
460 | QString | - | ||||||
461 | QFile::readLink() const | - | ||||||
462 | { | - | ||||||
463 | Q_D(const QFile); | - | ||||||
464 | return d->engine()->fileName(QAbstractFileEngine::LinkName); | - | ||||||
465 | } | - | ||||||
466 | - | |||||||
467 | /*! | - | ||||||
468 | \fn static QString QFile::symLinkTarget(const QString &fileName) | - | ||||||
469 | \since 4.2 | - | ||||||
470 | - | |||||||
471 | Returns the absolute path of the file or directory referred to by the | - | ||||||
472 | symlink (or shortcut on Windows) specified by \a fileName, or returns an | - | ||||||
473 | empty string if the \a fileName does not correspond to a symbolic link. | - | ||||||
474 | - | |||||||
475 | This name may not represent an existing file; it is only a string. | - | ||||||
476 | QFile::exists() returns \c true if the symlink points to an existing file. | - | ||||||
477 | */ | - | ||||||
478 | - | |||||||
479 | /*! | - | ||||||
480 | \obsolete | - | ||||||
481 | - | |||||||
482 | Use symLinkTarget() instead. | - | ||||||
483 | */ | - | ||||||
484 | QString | - | ||||||
485 | QFile::readLink(const QString &fileName) | - | ||||||
486 | { | - | ||||||
487 | return QFileInfo(fileName).readLink(); | - | ||||||
488 | } | - | ||||||
489 | - | |||||||
490 | /*! | - | ||||||
491 | Removes the file specified by fileName(). Returns \c true if successful; | - | ||||||
492 | otherwise returns \c false. | - | ||||||
493 | - | |||||||
494 | The file is closed before it is removed. | - | ||||||
495 | - | |||||||
496 | \sa setFileName() | - | ||||||
497 | */ | - | ||||||
498 | - | |||||||
499 | bool | - | ||||||
500 | QFile::remove() | - | ||||||
501 | { | - | ||||||
502 | Q_D(QFile); | - | ||||||
503 | if (d->fileName.isEmpty()) { | - | ||||||
504 | qWarning("QFile::remove: Empty or null file name"); | - | ||||||
505 | return false; | - | ||||||
506 | } | - | ||||||
507 | unsetError(); | - | ||||||
508 | close(); | - | ||||||
509 | if(error() == QFile::NoError) { | - | ||||||
510 | if (d->engine()->remove()) { | - | ||||||
511 | unsetError(); | - | ||||||
512 | return true; | - | ||||||
513 | } | - | ||||||
514 | d->setError(QFile::RemoveError, d->fileEngine->errorString()); | - | ||||||
515 | } | - | ||||||
516 | return false; | - | ||||||
517 | } | - | ||||||
518 | - | |||||||
519 | /*! | - | ||||||
520 | \overload | - | ||||||
521 | - | |||||||
522 | Removes the file specified by the \a fileName given. | - | ||||||
523 | - | |||||||
524 | Returns \c true if successful; otherwise returns \c false. | - | ||||||
525 | - | |||||||
526 | \sa remove() | - | ||||||
527 | */ | - | ||||||
528 | - | |||||||
529 | bool | - | ||||||
530 | QFile::remove(const QString &fileName) | - | ||||||
531 | { | - | ||||||
532 | return QFile(fileName).remove(); | - | ||||||
533 | } | - | ||||||
534 | - | |||||||
535 | /*! | - | ||||||
536 | Renames the file currently specified by fileName() to \a newName. | - | ||||||
537 | Returns \c true if successful; otherwise returns \c false. | - | ||||||
538 | - | |||||||
539 | If a file with the name \a newName already exists, rename() returns \c false | - | ||||||
540 | (i.e., QFile will not overwrite it). | - | ||||||
541 | - | |||||||
542 | The file is closed before it is renamed. | - | ||||||
543 | - | |||||||
544 | If the rename operation fails, Qt will attempt to copy this file's | - | ||||||
545 | contents to \a newName, and then remove this file, keeping only | - | ||||||
546 | \a newName. If that copy operation fails or this file can't be removed, | - | ||||||
547 | the destination file \a newName is removed to restore the old state. | - | ||||||
548 | - | |||||||
549 | \sa setFileName() | - | ||||||
550 | */ | - | ||||||
551 | - | |||||||
552 | bool | - | ||||||
553 | QFile::rename(const QString &newName) | - | ||||||
554 | { | - | ||||||
555 | Q_D(QFile); | - | ||||||
556 | if (d->fileName.isEmpty()) {
| 0-259 | ||||||
557 | qWarning("QFile::rename: Empty or null file name"); | - | ||||||
558 | return false; never executed: return false; | 0 | ||||||
559 | } | - | ||||||
560 | if (d->fileName == newName) {
| 1-258 | ||||||
561 | d->setError(QFile::RenameError, tr("Destination file is the same file.")); | - | ||||||
562 | return false; executed 1 time by 1 test: return false; Executed by:
| 1 | ||||||
563 | } | - | ||||||
564 | if (!exists()) {
| 2-256 | ||||||
565 | d->setError(QFile::RenameError, tr("Source file does not exist.")); | - | ||||||
566 | return false; executed 2 times by 1 test: return false; Executed by:
| 2 | ||||||
567 | } | - | ||||||
568 | // If the file exists and it is a case-changing rename ("foo" -> "Foo"), | - | ||||||
569 | // compare Ids to make sure it really is a different file. | - | ||||||
570 | if (QFile::exists(newName)) {
| 4-252 | ||||||
571 | if (d->fileName.compare(newName, Qt::CaseInsensitive)
| 0-4 | ||||||
572 | || QFileSystemEngine::id(QFileSystemEntry(d->fileName)) != QFileSystemEngine::id(QFileSystemEntry(newName))) {
| 0 | ||||||
573 | // ### Race condition. If a file is moved in after this, it /will/ be | - | ||||||
574 | // overwritten. On Unix, the proper solution is to use hardlinks: | - | ||||||
575 | // return ::link(old, new) && ::remove(old); | - | ||||||
576 | d->setError(QFile::RenameError, tr("Destination file exists")); | - | ||||||
577 | return false; executed 4 times by 1 test: return false; Executed by:
| 4 | ||||||
578 | } | - | ||||||
579 | #ifndef QT_NO_TEMPORARYFILE | - | ||||||
580 | // This #ifndef disables the workaround it encloses. Therefore, this configuration is not recommended. | - | ||||||
581 | #ifdef Q_OS_LINUX | - | ||||||
582 | // rename() on Linux simply does nothing when renaming "foo" to "Foo" on a case-insensitive | - | ||||||
583 | // FS, such as FAT32. Move the file away and rename in 2 steps to work around. | - | ||||||
584 | QTemporaryFile tempFile(d->fileName + QStringLiteralQLatin1String(".XXXXXX")); | - | ||||||
585 | tempFile.setAutoRemove(false); | - | ||||||
586 | if (!tempFile.open(QIODevice::ReadWrite)) {
| 0 | ||||||
587 | d->setError(QFile::RenameError, tempFile.errorString()); | - | ||||||
588 | return false; never executed: return false; | 0 | ||||||
589 | } | - | ||||||
590 | tempFile.close(); | - | ||||||
591 | if (!d->engine()->rename(tempFile.fileName())) {
| 0 | ||||||
592 | d->setError(QFile::RenameError, tr("Error while renaming.")); | - | ||||||
593 | return false; never executed: return false; | 0 | ||||||
594 | } | - | ||||||
595 | if (tempFile.rename(newName)) {
| 0 | ||||||
596 | d->fileEngine->setFileName(newName); | - | ||||||
597 | d->fileName = newName; | - | ||||||
598 | return true; never executed: return true; | 0 | ||||||
599 | } | - | ||||||
600 | d->setError(QFile::RenameError, tempFile.errorString()); | - | ||||||
601 | // We need to restore the original file. | - | ||||||
602 | if (!tempFile.rename(d->fileName)) {
| 0 | ||||||
603 | d->setError(QFile::RenameError, errorString() + QLatin1Char('\n') | - | ||||||
604 | + tr("Unable to restore from %1: %2"). | - | ||||||
605 | arg(QDir::toNativeSeparators(tempFile.fileName()), tempFile.errorString())); | - | ||||||
606 | } never executed: end of block | 0 | ||||||
607 | return false; never executed: return false; | 0 | ||||||
608 | #endif // Q_OS_LINUX | - | ||||||
609 | #endif // QT_NO_TEMPORARYFILE | - | ||||||
610 | } | - | ||||||
611 | unsetError(); | - | ||||||
612 | close(); | - | ||||||
613 | if(error() == QFile::NoError) {
| 0-252 | ||||||
614 | if (d->engine()->rename(newName)) {
| 4-248 | ||||||
615 | unsetError(); | - | ||||||
616 | // engine was able to handle the new name so we just reset it | - | ||||||
617 | d->fileEngine->setFileName(newName); | - | ||||||
618 | d->fileName = newName; | - | ||||||
619 | return true; executed 248 times by 14 tests: return true; Executed by:
| 248 | ||||||
620 | } | - | ||||||
621 | - | |||||||
622 | if (isSequential()) {
| 0-4 | ||||||
623 | d->setError(QFile::RenameError, tr("Will not rename sequential file using block copy")); | - | ||||||
624 | return false; never executed: return false; | 0 | ||||||
625 | } | - | ||||||
626 | - | |||||||
627 | QFile out(newName); | - | ||||||
628 | if (open(QIODevice::ReadOnly)) {
| 0-4 | ||||||
629 | if (out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
| 1-3 | ||||||
630 | bool error = false; | - | ||||||
631 | char block[4096]; | - | ||||||
632 | qint64 bytes; | - | ||||||
633 | while ((bytes = read(block, sizeof(block))) > 0) {
| 1 | ||||||
634 | if (bytes != out.write(block, bytes)) {
| 0-1 | ||||||
635 | d->setError(QFile::RenameError, out.errorString()); | - | ||||||
636 | error = true; | - | ||||||
637 | break; never executed: break; | 0 | ||||||
638 | } | - | ||||||
639 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||
640 | if (bytes == -1) {
| 0-1 | ||||||
641 | d->setError(QFile::RenameError, errorString()); | - | ||||||
642 | error = true; | - | ||||||
643 | } never executed: end of block | 0 | ||||||
644 | if(!error) {
| 0-1 | ||||||
645 | if (!remove()) {
| 0-1 | ||||||
646 | d->setError(QFile::RenameError, tr("Cannot remove source file")); | - | ||||||
647 | error = true; | - | ||||||
648 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||
649 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||
650 | if (error) {
| 0-1 | ||||||
651 | out.remove(); | - | ||||||
652 | } else { executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||
653 | d->fileEngine->setFileName(newName); | - | ||||||
654 | setPermissions(permissions()); | - | ||||||
655 | unsetError(); | - | ||||||
656 | setFileName(newName); | - | ||||||
657 | } never executed: end of block | 0 | ||||||
658 | close(); | - | ||||||
659 | return !error; executed 1 time by 1 test: return !error; Executed by:
| 1 | ||||||
660 | } | - | ||||||
661 | close(); | - | ||||||
662 | } executed 3 times by 3 tests: end of block Executed by:
| 3 | ||||||
663 | d->setError(QFile::RenameError, out.isOpen() ? errorString() : out.errorString()); | - | ||||||
664 | } executed 3 times by 3 tests: end of block Executed by:
| 3 | ||||||
665 | return false; executed 3 times by 3 tests: return false; Executed by:
| 3 | ||||||
666 | } | - | ||||||
667 | - | |||||||
668 | /*! | - | ||||||
669 | \overload | - | ||||||
670 | - | |||||||
671 | Renames the file \a oldName to \a newName. Returns \c true if | - | ||||||
672 | successful; otherwise returns \c false. | - | ||||||
673 | - | |||||||
674 | If a file with the name \a newName already exists, rename() returns \c false | - | ||||||
675 | (i.e., QFile will not overwrite it). | - | ||||||
676 | - | |||||||
677 | \sa rename() | - | ||||||
678 | */ | - | ||||||
679 | - | |||||||
680 | bool | - | ||||||
681 | QFile::rename(const QString &oldName, const QString &newName) | - | ||||||
682 | { | - | ||||||
683 | return QFile(oldName).rename(newName); | - | ||||||
684 | } | - | ||||||
685 | - | |||||||
686 | /*! | - | ||||||
687 | - | |||||||
688 | Creates a link named \a linkName that points to the file currently specified by | - | ||||||
689 | fileName(). What a link is depends on the underlying filesystem (be it a | - | ||||||
690 | shortcut on Windows or a symbolic link on Unix). Returns \c true if successful; | - | ||||||
691 | otherwise returns \c false. | - | ||||||
692 | - | |||||||
693 | This function will not overwrite an already existing entity in the file system; | - | ||||||
694 | in this case, \c link() will return false and set \l{QFile::}{error()} to | - | ||||||
695 | return \l{QFile::}{RenameError}. | - | ||||||
696 | - | |||||||
697 | \note To create a valid link on Windows, \a linkName must have a \c{.lnk} file extension. | - | ||||||
698 | - | |||||||
699 | \sa setFileName() | - | ||||||
700 | */ | - | ||||||
701 | - | |||||||
702 | bool | - | ||||||
703 | QFile::link(const QString &linkName) | - | ||||||
704 | { | - | ||||||
705 | Q_D(QFile); | - | ||||||
706 | if (d->fileName.isEmpty()) { | - | ||||||
707 | qWarning("QFile::link: Empty or null file name"); | - | ||||||
708 | return false; | - | ||||||
709 | } | - | ||||||
710 | QFileInfo fi(linkName); | - | ||||||
711 | if (d->engine()->link(fi.absoluteFilePath())) { | - | ||||||
712 | unsetError(); | - | ||||||
713 | return true; | - | ||||||
714 | } | - | ||||||
715 | d->setError(QFile::RenameError, d->fileEngine->errorString()); | - | ||||||
716 | return false; | - | ||||||
717 | } | - | ||||||
718 | - | |||||||
719 | /*! | - | ||||||
720 | \overload | - | ||||||
721 | - | |||||||
722 | Creates a link named \a linkName that points to the file \a fileName. What a link is | - | ||||||
723 | depends on the underlying filesystem (be it a shortcut on Windows | - | ||||||
724 | or a symbolic link on Unix). Returns \c true if successful; otherwise | - | ||||||
725 | returns \c false. | - | ||||||
726 | - | |||||||
727 | \sa link() | - | ||||||
728 | */ | - | ||||||
729 | - | |||||||
730 | bool | - | ||||||
731 | QFile::link(const QString &fileName, const QString &linkName) | - | ||||||
732 | { | - | ||||||
733 | return QFile(fileName).link(linkName); | - | ||||||
734 | } | - | ||||||
735 | - | |||||||
736 | /*! | - | ||||||
737 | Copies the file currently specified by fileName() to a file called | - | ||||||
738 | \a newName. Returns \c true if successful; otherwise returns \c false. | - | ||||||
739 | - | |||||||
740 | Note that if a file with the name \a newName already exists, | - | ||||||
741 | copy() returns \c false (i.e. QFile will not overwrite it). | - | ||||||
742 | - | |||||||
743 | The source file is closed before it is copied. | - | ||||||
744 | - | |||||||
745 | \sa setFileName() | - | ||||||
746 | */ | - | ||||||
747 | - | |||||||
748 | bool | - | ||||||
749 | QFile::copy(const QString &newName) | - | ||||||
750 | { | - | ||||||
751 | Q_D(QFile); | - | ||||||
752 | if (d->fileName.isEmpty()) { | - | ||||||
753 | qWarning("QFile::copy: Empty or null file name"); | - | ||||||
754 | return false; | - | ||||||
755 | } | - | ||||||
756 | if (QFile::exists(newName)) { | - | ||||||
757 | // ### Race condition. If a file is moved in after this, it /will/ be | - | ||||||
758 | // overwritten. On Unix, the proper solution is to use hardlinks: | - | ||||||
759 | // return ::link(old, new) && ::remove(old); See also rename(). | - | ||||||
760 | d->setError(QFile::CopyError, tr("Destination file exists")); | - | ||||||
761 | return false; | - | ||||||
762 | } | - | ||||||
763 | unsetError(); | - | ||||||
764 | close(); | - | ||||||
765 | if(error() == QFile::NoError) { | - | ||||||
766 | if (d->engine()->copy(newName)) { | - | ||||||
767 | unsetError(); | - | ||||||
768 | return true; | - | ||||||
769 | } else { | - | ||||||
770 | bool error = false; | - | ||||||
771 | if(!open(QFile::ReadOnly)) { | - | ||||||
772 | error = true; | - | ||||||
773 | d->setError(QFile::CopyError, tr("Cannot open %1 for input").arg(d->fileName)); | - | ||||||
774 | } else { | - | ||||||
775 | QString fileTemplate = QLatin1String("%1/qt_temp.XXXXXX"); | - | ||||||
776 | #ifdef QT_NO_TEMPORARYFILE | - | ||||||
777 | QFile out(fileTemplate.arg(QFileInfo(newName).path())); | - | ||||||
778 | if (!out.open(QIODevice::ReadWrite)) | - | ||||||
779 | error = true; | - | ||||||
780 | #else | - | ||||||
781 | QTemporaryFile out(fileTemplate.arg(QFileInfo(newName).path())); | - | ||||||
782 | if (!out.open()) { | - | ||||||
783 | out.setFileTemplate(fileTemplate.arg(QDir::tempPath())); | - | ||||||
784 | if (!out.open()) | - | ||||||
785 | error = true; | - | ||||||
786 | } | - | ||||||
787 | #endif | - | ||||||
788 | if (error) { | - | ||||||
789 | out.close(); | - | ||||||
790 | close(); | - | ||||||
791 | d->setError(QFile::CopyError, tr("Cannot open for output")); | - | ||||||
792 | } else { | - | ||||||
793 | char block[4096]; | - | ||||||
794 | qint64 totalRead = 0; | - | ||||||
795 | while(!atEnd()) { | - | ||||||
796 | qint64 in = read(block, sizeof(block)); | - | ||||||
797 | if (in <= 0) | - | ||||||
798 | break; | - | ||||||
799 | totalRead += in; | - | ||||||
800 | if(in != out.write(block, in)) { | - | ||||||
801 | close(); | - | ||||||
802 | d->setError(QFile::CopyError, tr("Failure to write block")); | - | ||||||
803 | error = true; | - | ||||||
804 | break; | - | ||||||
805 | } | - | ||||||
806 | } | - | ||||||
807 | - | |||||||
808 | if (totalRead != size()) { | - | ||||||
809 | // Unable to read from the source. The error string is | - | ||||||
810 | // already set from read(). | - | ||||||
811 | error = true; | - | ||||||
812 | } | - | ||||||
813 | if (!error && !out.rename(newName)) { | - | ||||||
814 | error = true; | - | ||||||
815 | close(); | - | ||||||
816 | d->setError(QFile::CopyError, tr("Cannot create %1 for output").arg(newName)); | - | ||||||
817 | } | - | ||||||
818 | #ifdef QT_NO_TEMPORARYFILE | - | ||||||
819 | if (error) | - | ||||||
820 | out.remove(); | - | ||||||
821 | #else | - | ||||||
822 | if (!error) | - | ||||||
823 | out.setAutoRemove(false); | - | ||||||
824 | #endif | - | ||||||
825 | } | - | ||||||
826 | } | - | ||||||
827 | if(!error) { | - | ||||||
828 | QFile::setPermissions(newName, permissions()); | - | ||||||
829 | close(); | - | ||||||
830 | unsetError(); | - | ||||||
831 | return true; | - | ||||||
832 | } | - | ||||||
833 | } | - | ||||||
834 | } | - | ||||||
835 | return false; | - | ||||||
836 | } | - | ||||||
837 | - | |||||||
838 | /*! | - | ||||||
839 | \overload | - | ||||||
840 | - | |||||||
841 | Copies the file \a fileName to \a newName. Returns \c true if successful; | - | ||||||
842 | otherwise returns \c false. | - | ||||||
843 | - | |||||||
844 | If a file with the name \a newName already exists, copy() returns \c false | - | ||||||
845 | (i.e., QFile will not overwrite it). | - | ||||||
846 | - | |||||||
847 | \sa rename() | - | ||||||
848 | */ | - | ||||||
849 | - | |||||||
850 | bool | - | ||||||
851 | QFile::copy(const QString &fileName, const QString &newName) | - | ||||||
852 | { | - | ||||||
853 | return QFile(fileName).copy(newName); | - | ||||||
854 | } | - | ||||||
855 | - | |||||||
856 | /*! | - | ||||||
857 | Opens the file using OpenMode \a mode, returning true if successful; | - | ||||||
858 | otherwise false. | - | ||||||
859 | - | |||||||
860 | The \a mode must be QIODevice::ReadOnly, QIODevice::WriteOnly, or | - | ||||||
861 | QIODevice::ReadWrite. It may also have additional flags, such as | - | ||||||
862 | QIODevice::Text and QIODevice::Unbuffered. | - | ||||||
863 | - | |||||||
864 | \note In \l{QIODevice::}{WriteOnly} or \l{QIODevice::}{ReadWrite} | - | ||||||
865 | mode, if the relevant file does not already exist, this function | - | ||||||
866 | will try to create a new file before opening it. | - | ||||||
867 | - | |||||||
868 | \sa QIODevice::OpenMode, setFileName() | - | ||||||
869 | */ | - | ||||||
870 | bool QFile::open(OpenMode mode) | - | ||||||
871 | { | - | ||||||
872 | Q_D(QFile); | - | ||||||
873 | if (isOpen()) { | - | ||||||
874 | qWarning("QFile::open: File (%s) already open", qPrintable(fileName())); | - | ||||||
875 | return false; | - | ||||||
876 | } | - | ||||||
877 | if (mode & Append) | - | ||||||
878 | mode |= WriteOnly; | - | ||||||
879 | - | |||||||
880 | unsetError(); | - | ||||||
881 | if ((mode & (ReadOnly | WriteOnly)) == 0) { | - | ||||||
882 | qWarning("QIODevice::open: File access not specified"); | - | ||||||
883 | return false; | - | ||||||
884 | } | - | ||||||
885 | - | |||||||
886 | // QIODevice provides the buffering, so there's no need to request it from the file engine. | - | ||||||
887 | if (d->engine()->open(mode | QIODevice::Unbuffered)) { | - | ||||||
888 | QIODevice::open(mode); | - | ||||||
889 | if (mode & Append) | - | ||||||
890 | seek(size()); | - | ||||||
891 | return true; | - | ||||||
892 | } | - | ||||||
893 | QFile::FileError err = d->fileEngine->error(); | - | ||||||
894 | if(err == QFile::UnspecifiedError) | - | ||||||
895 | err = QFile::OpenError; | - | ||||||
896 | d->setError(err, d->fileEngine->errorString()); | - | ||||||
897 | return false; | - | ||||||
898 | } | - | ||||||
899 | - | |||||||
900 | /*! | - | ||||||
901 | \overload | - | ||||||
902 | - | |||||||
903 | Opens the existing file handle \a fh in the given \a mode. | - | ||||||
904 | \a handleFlags may be used to specify additional options. | - | ||||||
905 | Returns \c true if successful; otherwise returns \c false. | - | ||||||
906 | - | |||||||
907 | Example: | - | ||||||
908 | \snippet code/src_corelib_io_qfile.cpp 3 | - | ||||||
909 | - | |||||||
910 | When a QFile is opened using this function, behaviour of close() is | - | ||||||
911 | controlled by the AutoCloseHandle flag. | - | ||||||
912 | If AutoCloseHandle is specified, and this function succeeds, | - | ||||||
913 | then calling close() closes the adopted handle. | - | ||||||
914 | Otherwise, close() does not actually close the file, but only flushes it. | - | ||||||
915 | - | |||||||
916 | \b{Warning:} | - | ||||||
917 | \list 1 | - | ||||||
918 | \li If \a fh does not refer to a regular file, e.g., it is \c stdin, | - | ||||||
919 | \c stdout, or \c stderr, you may not be able to seek(). size() | - | ||||||
920 | returns \c 0 in those cases. See QIODevice::isSequential() for | - | ||||||
921 | more information. | - | ||||||
922 | \li Since this function opens the file without specifying the file name, | - | ||||||
923 | you cannot use this QFile with a QFileInfo. | - | ||||||
924 | \endlist | - | ||||||
925 | - | |||||||
926 | \sa close() | - | ||||||
927 | - | |||||||
928 | \b{Note for the Windows Platform} | - | ||||||
929 | - | |||||||
930 | \a fh must be opened in binary mode (i.e., the mode string must contain | - | ||||||
931 | 'b', as in "rb" or "wb") when accessing files and other random-access | - | ||||||
932 | devices. Qt will translate the end-of-line characters if you pass | - | ||||||
933 | QIODevice::Text to \a mode. Sequential devices, such as stdin and stdout, | - | ||||||
934 | are unaffected by this limitation. | - | ||||||
935 | - | |||||||
936 | You need to enable support for console applications in order to use the | - | ||||||
937 | stdin, stdout and stderr streams at the console. To do this, add the | - | ||||||
938 | following declaration to your application's project file: | - | ||||||
939 | - | |||||||
940 | \snippet code/src_corelib_io_qfile.cpp 4 | - | ||||||
941 | */ | - | ||||||
942 | bool QFile::open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags) | - | ||||||
943 | { | - | ||||||
944 | Q_D(QFile); | - | ||||||
945 | if (isOpen()) { | - | ||||||
946 | qWarning("QFile::open: File (%s) already open", qPrintable(fileName())); | - | ||||||
947 | return false; | - | ||||||
948 | } | - | ||||||
949 | if (mode & Append) | - | ||||||
950 | mode |= WriteOnly; | - | ||||||
951 | unsetError(); | - | ||||||
952 | if ((mode & (ReadOnly | WriteOnly)) == 0) { | - | ||||||
953 | qWarning("QFile::open: File access not specified"); | - | ||||||
954 | return false; | - | ||||||
955 | } | - | ||||||
956 | if (d->openExternalFile(mode, fh, handleFlags)) { | - | ||||||
957 | QIODevice::open(mode); | - | ||||||
958 | if (!(mode & Append) && !isSequential()) { | - | ||||||
959 | qint64 pos = (qint64)QT_FTELL(fh); | - | ||||||
960 | if (pos != -1) { | - | ||||||
961 | // Skip redundant checks in QFileDevice::seek(). | - | ||||||
962 | QIODevice::seek(pos); | - | ||||||
963 | } | - | ||||||
964 | } | - | ||||||
965 | return true; | - | ||||||
966 | } | - | ||||||
967 | return false; | - | ||||||
968 | } | - | ||||||
969 | - | |||||||
970 | /*! | - | ||||||
971 | \overload | - | ||||||
972 | - | |||||||
973 | Opens the existing file descriptor \a fd in the given \a mode. | - | ||||||
974 | \a handleFlags may be used to specify additional options. | - | ||||||
975 | Returns \c true if successful; otherwise returns \c false. | - | ||||||
976 | - | |||||||
977 | When a QFile is opened using this function, behaviour of close() is | - | ||||||
978 | controlled by the AutoCloseHandle flag. | - | ||||||
979 | If AutoCloseHandle is specified, and this function succeeds, | - | ||||||
980 | then calling close() closes the adopted handle. | - | ||||||
981 | Otherwise, close() does not actually close the file, but only flushes it. | - | ||||||
982 | - | |||||||
983 | The QFile that is opened using this function is automatically set | - | ||||||
984 | to be in raw mode; this means that the file input/output functions | - | ||||||
985 | are slow. If you run into performance issues, you should try to | - | ||||||
986 | use one of the other open functions. | - | ||||||
987 | - | |||||||
988 | \warning If \a fd is not a regular file, e.g, it is 0 (\c stdin), | - | ||||||
989 | 1 (\c stdout), or 2 (\c stderr), you may not be able to seek(). In | - | ||||||
990 | those cases, size() returns \c 0. See QIODevice::isSequential() | - | ||||||
991 | for more information. | - | ||||||
992 | - | |||||||
993 | \warning Since this function opens the file without specifying the file name, | - | ||||||
994 | you cannot use this QFile with a QFileInfo. | - | ||||||
995 | - | |||||||
996 | \sa close() | - | ||||||
997 | */ | - | ||||||
998 | bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags) | - | ||||||
999 | { | - | ||||||
1000 | Q_D(QFile); | - | ||||||
1001 | if (isOpen()) { | - | ||||||
1002 | qWarning("QFile::open: File (%s) already open", qPrintable(fileName())); | - | ||||||
1003 | return false; | - | ||||||
1004 | } | - | ||||||
1005 | if (mode & Append) | - | ||||||
1006 | mode |= WriteOnly; | - | ||||||
1007 | unsetError(); | - | ||||||
1008 | if ((mode & (ReadOnly | WriteOnly)) == 0) { | - | ||||||
1009 | qWarning("QFile::open: File access not specified"); | - | ||||||
1010 | return false; | - | ||||||
1011 | } | - | ||||||
1012 | if (d->openExternalFile(mode, fd, handleFlags)) { | - | ||||||
1013 | QIODevice::open(mode); | - | ||||||
1014 | if (!(mode & Append) && !isSequential()) { | - | ||||||
1015 | qint64 pos = (qint64)QT_LSEEK(fd, QT_OFF_T(0), SEEK_CUR); | - | ||||||
1016 | if (pos != -1) { | - | ||||||
1017 | // Skip redundant checks in QFileDevice::seek(). | - | ||||||
1018 | QIODevice::seek(pos); | - | ||||||
1019 | } | - | ||||||
1020 | } | - | ||||||
1021 | return true; | - | ||||||
1022 | } | - | ||||||
1023 | return false; | - | ||||||
1024 | } | - | ||||||
1025 | - | |||||||
1026 | /*! | - | ||||||
1027 | \reimp | - | ||||||
1028 | */ | - | ||||||
1029 | bool QFile::resize(qint64 sz) | - | ||||||
1030 | { | - | ||||||
1031 | return QFileDevice::resize(sz); // for now | - | ||||||
1032 | } | - | ||||||
1033 | - | |||||||
1034 | /*! | - | ||||||
1035 | \overload | - | ||||||
1036 | - | |||||||
1037 | Sets \a fileName to size (in bytes) \a sz. Returns \c true if the file if | - | ||||||
1038 | the resize succeeds; false otherwise. If \a sz is larger than \a | - | ||||||
1039 | fileName currently is the new bytes will be set to 0, if \a sz is | - | ||||||
1040 | smaller the file is simply truncated. | - | ||||||
1041 | - | |||||||
1042 | \sa resize() | - | ||||||
1043 | */ | - | ||||||
1044 | - | |||||||
1045 | bool | - | ||||||
1046 | QFile::resize(const QString &fileName, qint64 sz) | - | ||||||
1047 | { | - | ||||||
1048 | return QFile(fileName).resize(sz); | - | ||||||
1049 | } | - | ||||||
1050 | - | |||||||
1051 | /*! | - | ||||||
1052 | \reimp | - | ||||||
1053 | */ | - | ||||||
1054 | QFile::Permissions QFile::permissions() const | - | ||||||
1055 | { | - | ||||||
1056 | return QFileDevice::permissions(); // for now | - | ||||||
1057 | } | - | ||||||
1058 | - | |||||||
1059 | /*! | - | ||||||
1060 | \overload | - | ||||||
1061 | - | |||||||
1062 | Returns the complete OR-ed together combination of | - | ||||||
1063 | QFile::Permission for \a fileName. | - | ||||||
1064 | */ | - | ||||||
1065 | - | |||||||
1066 | QFile::Permissions | - | ||||||
1067 | QFile::permissions(const QString &fileName) | - | ||||||
1068 | { | - | ||||||
1069 | return QFile(fileName).permissions(); | - | ||||||
1070 | } | - | ||||||
1071 | - | |||||||
1072 | /*! | - | ||||||
1073 | Sets the permissions for the file to the \a permissions specified. | - | ||||||
1074 | Returns \c true if successful, or \c false if the permissions cannot be | - | ||||||
1075 | modified. | - | ||||||
1076 | - | |||||||
1077 | \warning This function does not manipulate ACLs, which may limit its | - | ||||||
1078 | effectiveness. | - | ||||||
1079 | - | |||||||
1080 | \sa permissions(), setFileName() | - | ||||||
1081 | */ | - | ||||||
1082 | - | |||||||
1083 | bool QFile::setPermissions(Permissions permissions) | - | ||||||
1084 | { | - | ||||||
1085 | return QFileDevice::setPermissions(permissions); // for now | - | ||||||
1086 | } | - | ||||||
1087 | - | |||||||
1088 | /*! | - | ||||||
1089 | \overload | - | ||||||
1090 | - | |||||||
1091 | Sets the permissions for \a fileName file to \a permissions. | - | ||||||
1092 | */ | - | ||||||
1093 | - | |||||||
1094 | bool | - | ||||||
1095 | QFile::setPermissions(const QString &fileName, Permissions permissions) | - | ||||||
1096 | { | - | ||||||
1097 | return QFile(fileName).setPermissions(permissions); | - | ||||||
1098 | } | - | ||||||
1099 | - | |||||||
1100 | /*! | - | ||||||
1101 | \reimp | - | ||||||
1102 | */ | - | ||||||
1103 | qint64 QFile::size() const | - | ||||||
1104 | { | - | ||||||
1105 | return QFileDevice::size(); // for now | - | ||||||
1106 | } | - | ||||||
1107 | - | |||||||
1108 | QT_END_NAMESPACE | - | ||||||
Source code | Switch to Preprocessed file |