Removing unnecessary chunking and stat'ing when reading QIODevice
[qt-netbsd.git] / tests / auto / qfile / tst_qfile.cpp
blobcf46ce1616f4e66540e20220194d09e02e332275
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
43 #include <QtTest/QtTest>
44 #include <qplatformdefs.h>
46 #include <QAbstractFileEngine>
47 #include <QFSFileEngine>
48 #include <QCoreApplication>
49 #include <QDebug>
50 #include <QDir>
51 #include <QFile>
52 #include <QFileInfo>
53 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
54 #include <QHostInfo>
55 #endif
56 #include <QProcess>
57 #ifndef Q_OS_WIN
58 # include <sys/types.h>
59 # include <unistd.h>
60 #endif
61 #ifdef Q_OS_MAC
62 # include <sys/mount.h>
63 #elif defined(Q_OS_LINUX)
64 # include <sys/vfs.h>
65 #elif defined(Q_OS_FREEBSD)
66 # include <sys/param.h>
67 # include <sys/mount.h>
68 #elif defined(Q_OS_IRIX)
69 # include <sys/statfs.h>
70 #elif defined(Q_OS_WINCE)
71 # include <qplatformdefs.h>
72 # include <private/qfsfileengine_p.h>
73 #endif
75 #include <stdio.h>
76 #include "../network-settings.h"
78 #if defined(Q_OS_SYMBIAN)
79 # define SRCDIR ""
80 #endif
82 #ifndef STDIN_FILENO
83 #define STDIN_FILENO 0
84 #endif
86 #ifndef STDOUT_FILENO
87 #define STDOUT_FILENO 1
88 #endif
90 #ifndef STDERR_FILENO
91 #define STDERR_FILENO 2
92 #endif
94 #ifndef QT_OPEN_BINARY
95 #define QT_OPEN_BINARY 0
96 #endif
98 Q_DECLARE_METATYPE(QFile::FileError)
100 //TESTED_CLASS=
101 //TESTED_FILES=
103 class tst_QFile : public QObject
105 Q_OBJECT
107 public:
108 tst_QFile();
109 virtual ~tst_QFile();
112 public slots:
113 void init();
114 void cleanup();
115 private slots:
116 void initTestCase();
117 void cleanupTestCase();
118 void exists();
119 void open_data();
120 void open();
121 void openUnbuffered();
122 void size_data();
123 void size();
124 void sizeNoExist();
125 void seek();
126 void setSize();
127 void setSizeSeek();
128 void atEnd();
129 void readLine();
130 void readLine2();
131 void readLineNullInLine();
132 void readAllStdin();
133 void readLineStdin();
134 void readLineStdin_lineByLine();
135 void text();
136 void missingEndOfLine();
137 void readBlock();
138 void getch();
139 void ungetChar();
140 void createFile();
141 void append();
142 void permissions_data();
143 void permissions();
144 void setPermissions();
145 void copy();
146 void copyAfterFail();
147 void copyRemovesTemporaryFile() const;
148 void copyShouldntOverwrite();
149 void copyFallback();
150 void link();
151 void linkToDir();
152 void absolutePathLinkToRelativePath();
153 void readBrokenLink();
154 void readTextFile_data();
155 void readTextFile();
156 void readTextFile2();
157 void writeTextFile_data();
158 void writeTextFile();
159 /* void largeFileSupport(); */
160 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
161 void largeUncFileSupport();
162 #endif
163 void tailFile();
164 void flush();
165 void bufferedRead();
166 void isSequential();
167 void encodeName();
168 void truncate();
169 void seekToPos();
170 void FILEReadWrite();
171 void i18nFileName_data();
172 void i18nFileName();
173 void longFileName_data();
174 void longFileName();
175 void fileEngineHandler();
176 void useQFileInAFileHandler();
177 void getCharFF();
178 void remove_and_exists();
179 void removeOpenFile();
180 void fullDisk();
181 void writeLargeDataBlock_data();
182 void writeLargeDataBlock();
183 void readFromWriteOnlyFile();
184 void writeToReadOnlyFile();
185 void virtualFile();
186 void textFile();
187 void rename_data();
188 void rename();
189 void renameWithAtEndSpecialFile() const;
190 void renameFallback();
191 void renameMultiple();
192 void appendAndRead();
193 void miscWithUncPathAsCurrentDir();
194 void standarderror();
195 void handle();
197 void readEof_data();
198 void readEof();
200 void map_data();
201 void map();
202 void mapResource_data();
203 void mapResource();
204 void mapOpenMode_data();
205 void mapOpenMode();
207 void openStandardStreams();
209 // --- Task related tests below this line
210 void task167217();
212 void openDirectory();
213 void writeNothing();
215 public:
216 // disabled this test for the moment... it hangs
217 void invalidFile_data();
218 void invalidFile();
220 private:
221 enum FileType { OpenQFile, OpenFd, OpenStream };
223 bool openFd(QFile &file, QIODevice::OpenMode mode)
225 int fdMode = QT_OPEN_LARGEFILE | QT_OPEN_BINARY;
227 // File will be truncated if in Write mode.
228 if (mode & QIODevice::WriteOnly)
229 fdMode |= QT_OPEN_WRONLY | QT_OPEN_TRUNC;
230 if (mode & QIODevice::ReadOnly)
231 fdMode |= QT_OPEN_RDONLY;
233 fd_ = QT_OPEN(qPrintable(file.fileName()), fdMode);
235 return (-1 != fd_) && file.open(fd_, mode);
238 bool openStream(QFile &file, QIODevice::OpenMode mode)
240 char const *streamMode = "";
242 // File will be truncated if in Write mode.
243 if (mode & QIODevice::WriteOnly)
244 streamMode = "wb+";
245 else if (mode & QIODevice::ReadOnly)
246 streamMode = "rb";
248 stream_ = QT_FOPEN(qPrintable(file.fileName()), streamMode);
250 return stream_ && file.open(stream_, mode);
253 bool openFile(QFile &file, QIODevice::OpenMode mode, FileType type = OpenQFile)
255 if (mode & QIODevice::WriteOnly && !file.exists())
257 // Make sure the file exists
258 QFile createFile(file.fileName());
259 if (!createFile.open(QIODevice::ReadWrite))
260 return false;
263 // Note: openFd and openStream will truncate the file if write mode.
264 switch (type)
266 case OpenQFile:
267 return file.open(mode);
269 case OpenFd:
270 return openFd(file, mode);
272 case OpenStream:
273 return openStream(file, mode);
276 return false;
279 void closeFile(QFile &file)
281 file.close();
283 if (-1 != fd_)
284 QT_CLOSE(fd_);
285 if (stream_)
286 ::fclose(stream_);
288 fd_ = -1;
289 stream_ = 0;
292 int fd_;
293 FILE *stream_;
296 tst_QFile::tst_QFile()
300 tst_QFile::~tst_QFile()
305 void tst_QFile::init()
307 // TODO: Add initialization code here.
308 // This will be executed immediately before each test is run.
309 fd_ = -1;
310 stream_ = 0;
313 void tst_QFile::cleanup()
315 // TODO: Add cleanup code here.
316 // This will be executed immediately after each test is run.
318 // for copyFallback()
319 if (QFile::exists("file-copy-destination.txt")) {
320 QFile::setPermissions("file-copy-destination.txt",
321 QFile::ReadOwner | QFile::WriteOwner);
322 QFile::remove("file-copy-destination.txt");
325 // for renameFallback()
326 QFile::remove("file-rename-destination.txt");
328 // for copyAfterFail()
329 QFile::remove("file-to-be-copied.txt");
330 QFile::remove("existing-file.txt");
331 QFile::remove("copied-file-1.txt");
332 QFile::remove("copied-file-2.txt");
334 // for renameMultiple()
335 QFile::remove("file-to-be-renamed.txt");
336 QFile::remove("existing-file.txt");
337 QFile::remove("file-renamed-once.txt");
338 QFile::remove("file-renamed-twice.txt");
340 if (-1 != fd_)
341 QT_CLOSE(fd_);
342 if (stream_)
343 ::fclose(stream_);
346 void tst_QFile::initTestCase()
348 QFile::remove("noreadfile");
350 // create a file and make it read-only
351 QFile file("readonlyfile");
352 file.open(QFile::WriteOnly);
353 file.write("a", 1);
354 file.close();
355 file.setPermissions(QFile::ReadOwner);
357 // create another file and make it not readable
358 file.setFileName("noreadfile");
359 file.open(QFile::WriteOnly);
360 file.write("b", 1);
361 file.close();
362 file.setPermissions(0);
365 void tst_QFile::cleanupTestCase()
367 // clean up the files we created
368 QFile::remove("readonlyfile");
369 QFile::remove("noreadfile");
370 QFile::remove("myLink.lnk");
371 QFile::remove("appendme.txt");
372 QFile::remove("createme.txt");
373 QFile::remove("file.txt");
374 QFile::remove("genfile.txt");
375 QFile::remove("seekToPos.txt");
376 QFile::remove("setsizeseek.txt");
377 QFile::remove("stdfile.txt");
378 QFile::remove("textfile.txt");
379 QFile::remove("truncate.txt");
380 QFile::remove("winfile.txt");
381 QFile::remove("writeonlyfile");
382 QFile::remove("largeblockfile.txt");
383 QFile::remove("tst_qfile_copy.cpp");
384 QFile::remove("nullinline.txt");
385 QFile::remove("myLink2.lnk");
386 QFile::remove("resources");
387 QFile::remove("qfile_map_testfile");
390 //------------------------------------------
391 // The 'testfile' is currently just a
392 // testfile. The path of this file, the
393 // attributes and the contents itself
394 // will be changed as far as we have a
395 // proper way to handle files in the
396 // testing enviroment.
397 //------------------------------------------
399 void tst_QFile::exists()
401 QFile f( SRCDIR "testfile.txt" );
402 QCOMPARE( f.exists(), (bool)TRUE );
404 QFile file("nobodyhassuchafile");
405 file.remove();
406 QVERIFY(!file.exists());
408 QFile file2("nobodyhassuchafile");
409 QVERIFY(file2.open(QIODevice::WriteOnly));
410 file2.close();
412 QVERIFY(file.exists());
414 QVERIFY(file.open(QIODevice::WriteOnly));
415 file.close();
416 QVERIFY(file.exists());
418 file.remove();
419 QVERIFY(!file.exists());
421 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
422 QFile unc("//" + QtNetworkSettings::winServerName() + "/testshare/readme.txt");
423 QVERIFY(unc.exists());
424 #endif
427 void tst_QFile::open_data()
429 QTest::addColumn<QString>("filename");
430 QTest::addColumn<int>("mode");
431 QTest::addColumn<bool>("ok");
432 QTest::addColumn<QFile::FileError>("status");
434 #ifdef Q_OS_MAC
435 static const QString denied("Operation not permitted");
436 #else
437 static const QString denied("Permission denied");
438 #endif
439 QTest::newRow( "exist_readOnly" )
440 << QString(SRCDIR "testfile.txt") << int(QIODevice::ReadOnly)
441 << (bool)TRUE << QFile::NoError;
443 QTest::newRow( "exist_writeOnly" )
444 << QString("readonlyfile")
445 << int(QIODevice::WriteOnly)
446 << (bool)FALSE
447 << QFile::OpenError;
449 QTest::newRow( "exist_append" )
450 << QString("readonlyfile") << int(QIODevice::Append)
451 << (bool)FALSE << QFile::OpenError;
453 QTest::newRow( "nonexist_readOnly" )
454 << QString("nonExist.txt") << int(QIODevice::ReadOnly)
455 << (bool)FALSE << QFile::OpenError;
457 QTest::newRow("emptyfile")
458 << QString("")
459 << int(QIODevice::ReadOnly)
460 << (bool)FALSE
461 << QFile::OpenError;
463 QTest::newRow("nullfile") << QString() << int(QIODevice::ReadOnly) << (bool)FALSE
464 << QFile::OpenError;
466 QTest::newRow("two-dots") << QString(SRCDIR "two.dots.file") << int(QIODevice::ReadOnly) << (bool)TRUE
467 << QFile::NoError;
469 QTest::newRow("readonlyfile") << QString("readonlyfile") << int(QIODevice::WriteOnly)
470 << (bool)FALSE << QFile::OpenError;
471 QTest::newRow("noreadfile") << QString("noreadfile") << int(QIODevice::ReadOnly)
472 << (bool)FALSE << QFile::OpenError;
473 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
474 QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly)
475 << (bool)TRUE << QFile::NoError;
476 QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testsharewritable/test.pri" << int(QIODevice::ReadOnly)
477 << true << QFile::NoError;
478 #endif
481 void tst_QFile::open()
483 QFETCH( QString, filename );
484 QFETCH( int, mode );
486 QFile f( filename );
488 QFETCH( bool, ok );
490 #if defined(Q_OS_SYMBIAN)
491 if (qstrcmp(QTest::currentDataTag(), "noreadfile") == 0)
492 QSKIP("Symbian does not support non-readable files", SkipSingle);
493 #elif defined(Q_OS_UNIX)
494 if (::getuid() == 0)
495 // root and Chuck Norris don't care for file permissions. Skip.
496 QSKIP("Running this test as root doesn't make sense", SkipAll);
497 #endif
499 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
500 QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort);
501 #endif
502 if (filename.isEmpty())
503 QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified");
505 QCOMPARE(f.open( QIODevice::OpenMode(mode) ), ok);
507 QTEST( f.error(), "status" );
510 void tst_QFile::openUnbuffered()
512 QFile file(SRCDIR "testfile.txt");
513 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
514 char c = '\0';
515 QVERIFY(file.seek(1));
516 QCOMPARE(file.pos(), qint64(1));
517 QVERIFY(file.getChar(&c));
518 QCOMPARE(file.pos(), qint64(2));
519 char d = '\0';
520 QVERIFY(file.seek(3));
521 QCOMPARE(file.pos(), qint64(3));
522 QVERIFY(file.getChar(&d));
523 QCOMPARE(file.pos(), qint64(4));
524 QVERIFY(file.seek(1));
525 QCOMPARE(file.pos(), qint64(1));
526 char c2 = '\0';
527 QVERIFY(file.getChar(&c2));
528 QCOMPARE(file.pos(), qint64(2));
529 QVERIFY(file.seek(3));
530 QCOMPARE(file.pos(), qint64(3));
531 char d2 = '\0';
532 QVERIFY(file.getChar(&d2));
533 QCOMPARE(file.pos(), qint64(4));
534 QCOMPARE(c, c2);
535 QCOMPARE(d, d2);
536 QCOMPARE(c, '-');
537 QCOMPARE(d, '-');
540 void tst_QFile::size_data()
542 QTest::addColumn<QString>("filename");
543 QTest::addColumn<qint64>("size");
545 QTest::newRow( "exist01" ) << QString(SRCDIR "testfile.txt") << (qint64)245;
546 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
547 // Only test UNC on Windows./
548 QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testsharewritable/test.pri") << (qint64)34;
549 #endif
552 void tst_QFile::size()
554 QFETCH( QString, filename );
555 QFETCH( qint64, size );
558 QFile f( filename );
559 QCOMPARE( f.size(), size );
561 QVERIFY( f.open(QIODevice::ReadOnly) );
562 QCOMPARE( f.size(), size );
566 QFile f;
567 int fd = QT_OPEN(filename.toLocal8Bit().constData(), QT_OPEN_RDONLY);
568 QVERIFY( fd != -1 );
569 QVERIFY( f.open(fd, QIODevice::ReadOnly) );
570 QCOMPARE( f.size(), size );
572 f.close();
573 QT_CLOSE(fd);
577 QFile f;
578 FILE* stream = QT_FOPEN(filename.toLocal8Bit().constData(), "rb");
579 QVERIFY( stream );
580 QVERIFY( f.open(stream, QIODevice::ReadOnly) );
581 QCOMPARE( f.size(), size );
583 f.close();
584 fclose(stream);
588 void tst_QFile::sizeNoExist()
590 QFile file("nonexist01");
591 QVERIFY( !file.exists() );
592 QCOMPARE( file.size(), (qint64)0 );
593 QVERIFY( !file.open(QIODevice::ReadOnly) );
596 void tst_QFile::seek()
598 QFile::remove("newfile.txt");
599 QFile file("newfile.txt");
600 file.open(QIODevice::WriteOnly);
601 QCOMPARE(file.size(), qint64(0));
602 QCOMPARE(file.pos(), qint64(0));
603 QVERIFY(file.seek(10));
604 QCOMPARE(file.pos(), qint64(10));
605 QCOMPARE(file.size(), qint64(0));
606 QFile::remove("newfile.txt");
609 void tst_QFile::setSize()
611 DEPENDS_ON( "size" );
613 if ( QFile::exists( "createme.txt" ) )
614 QFile::remove( "createme.txt" );
615 QVERIFY( !QFile::exists( "createme.txt" ) );
617 QFile f("createme.txt");
618 QVERIFY(f.open(QIODevice::Truncate | QIODevice::ReadWrite));
619 f.putChar('a');
621 f.seek(0);
622 char c = '\0';
623 f.getChar(&c);
624 QCOMPARE(c, 'a');
626 QCOMPARE(f.size(), (qlonglong)1);
627 bool ok = f.resize(99);
628 QVERIFY(ok);
629 QCOMPARE(f.size(), (qlonglong)99);
631 f.seek(0);
632 c = '\0';
633 f.getChar(&c);
634 QCOMPARE(c, 'a');
636 QVERIFY(f.resize(1));
637 QCOMPARE(f.size(), (qlonglong)1);
639 f.seek(0);
640 c = '\0';
641 f.getChar(&c);
642 QCOMPARE(c, 'a');
644 f.close();
646 QCOMPARE(f.size(), (qlonglong)1);
647 QVERIFY(f.resize(100));
648 QCOMPARE(f.size(), (qlonglong)100);
649 QVERIFY(f.resize(50));
650 QCOMPARE(f.size(), (qlonglong)50);
653 void tst_QFile::setSizeSeek()
655 QFile::remove("setsizeseek.txt");
656 QFile f("setsizeseek.txt");
657 QVERIFY(f.open(QFile::WriteOnly));
658 f.write("ABCD");
660 QCOMPARE(f.pos(), qint64(4));
661 f.resize(2);
662 QCOMPARE(f.pos(), qint64(2));
663 f.resize(4);
664 QCOMPARE(f.pos(), qint64(2));
665 f.resize(0);
666 QCOMPARE(f.pos(), qint64(0));
667 f.resize(4);
668 QCOMPARE(f.pos(), qint64(0));
670 f.seek(3);
671 QCOMPARE(f.pos(), qint64(3));
672 f.resize(2);
673 QCOMPARE(f.pos(), qint64(2));
676 void tst_QFile::atEnd()
678 QFile f( SRCDIR "testfile.txt" );
679 QVERIFY(f.open( QIODevice::ReadOnly ));
681 int size = f.size();
682 f.seek( size );
684 bool end = f.atEnd();
685 f.close();
686 QCOMPARE( end, (bool)TRUE );
689 void tst_QFile::readLine()
691 QFile f( SRCDIR "testfile.txt" );
692 QVERIFY(f.open( QIODevice::ReadOnly ));
694 int i = 0;
695 char p[128];
696 int foo;
697 while ( (foo=f.readLine( p, 128 )) > 0 ) {
698 ++i;
699 if ( i == 5 ) {
700 QCOMPARE( p[0], 'T' );
701 QCOMPARE( p[3], 's' );
702 QCOMPARE( p[11], 'i' );
705 f.close();
706 QCOMPARE( i, 6 );
709 void tst_QFile::readLine2()
711 QFile f( SRCDIR "testfile.txt" );
712 f.open( QIODevice::ReadOnly );
714 char p[128];
715 QCOMPARE(f.readLine(p, 60), qlonglong(59));
716 QCOMPARE(f.readLine(p, 60), qlonglong(59));
717 memset(p, '@', sizeof(p));
718 QCOMPARE(f.readLine(p, 60), qlonglong(59));
720 QCOMPARE(p[57], '-');
721 QCOMPARE(p[58], '\n');
722 QCOMPARE(p[59], '\0');
723 QCOMPARE(p[60], '@');
726 void tst_QFile::readLineNullInLine()
728 QFile::remove("nullinline.txt");
729 QFile file("nullinline.txt");
730 QVERIFY(file.open(QIODevice::ReadWrite));
731 QVERIFY(file.write("linewith\0null\nanotherline\0withnull\n\0\nnull\0", 42) > 0);
732 QVERIFY(file.flush());
733 file.reset();
735 QCOMPARE(file.readLine(), QByteArray("linewith\0null\n", 14));
736 QCOMPARE(file.readLine(), QByteArray("anotherline\0withnull\n", 21));
737 QCOMPARE(file.readLine(), QByteArray("\0\n", 2));
738 QCOMPARE(file.readLine(), QByteArray("null\0", 5));
739 QCOMPARE(file.readLine(), QByteArray());
742 void tst_QFile::readAllStdin()
744 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
745 QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll);
746 #endif
747 #if defined(QT_NO_PROCESS)
748 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
749 #else
750 QByteArray lotsOfData(1024, '@'); // 10 megs
752 QProcess process;
753 process.start("stdinprocess/stdinprocess all");
754 QVERIFY( process.waitForStarted() );
755 for (int i = 0; i < 5; ++i) {
756 QTest::qWait(1000);
757 process.write(lotsOfData);
758 while (process.bytesToWrite() > 0) {
759 QVERIFY(process.waitForBytesWritten());
763 process.closeWriteChannel();
764 process.waitForFinished();
765 QCOMPARE(process.readAll().size(), lotsOfData.size() * 5);
766 #endif
769 void tst_QFile::readLineStdin()
771 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
772 QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll);
773 #endif
774 #if defined(QT_NO_PROCESS)
775 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
776 #else
778 QByteArray lotsOfData(1024, '@'); // 10 megs
779 for (int i = 0; i < lotsOfData.size(); ++i) {
780 if ((i % 32) == 31)
781 lotsOfData[i] = '\n';
782 else
783 lotsOfData[i] = char('0' + i % 32);
786 for (int i = 0; i < 2; ++i) {
787 QProcess process;
788 process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
789 for (int i = 0; i < 5; ++i) {
790 QTest::qWait(1000);
791 process.write(lotsOfData);
792 while (process.bytesToWrite() > 0) {
793 QVERIFY(process.waitForBytesWritten());
797 process.closeWriteChannel();
798 QVERIFY(process.waitForFinished(5000));
800 QByteArray array = process.readAll();
801 QCOMPARE(array.size(), lotsOfData.size() * 5);
802 for (int i = 0; i < array.size(); ++i) {
803 if ((i % 32) == 31)
804 QCOMPARE(char(array[i]), '\n');
805 else
806 QCOMPARE(char(array[i]), char('0' + i % 32));
809 #endif
812 void tst_QFile::readLineStdin_lineByLine()
814 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
815 QSKIP("Currently no stdin/out supported for Windows CE", SkipAll);
816 #endif
817 #if defined(QT_NO_PROCESS)
818 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
819 #else
820 for (int i = 0; i < 2; ++i) {
821 QProcess process;
822 process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
823 QVERIFY(process.waitForStarted());
825 for (int j = 0; j < 3; ++j) {
826 QByteArray line = "line " + QByteArray::number(j) + "\n";
827 QCOMPARE(process.write(line), qint64(line.size()));
828 QVERIFY(process.waitForBytesWritten(2000));
829 if (process.bytesAvailable() == 0)
830 QVERIFY(process.waitForReadyRead(2000));
831 QCOMPARE(process.readAll(), line);
834 process.closeWriteChannel();
835 QVERIFY(process.waitForFinished(5000));
837 #endif
840 void tst_QFile::text()
842 // dosfile.txt is a binary CRLF file
843 QFile file(SRCDIR "dosfile.txt");
844 QVERIFY(file.open(QFile::Text | QFile::ReadOnly));
845 QCOMPARE(file.readLine(),
846 QByteArray("/dev/system/root / reiserfs acl,user_xattr 1 1\n"));
847 QCOMPARE(file.readLine(),
848 QByteArray("/dev/sda1 /boot ext3 acl,user_xattr 1 2\n"));
849 file.ungetChar('\n');
850 file.ungetChar('2');
851 QCOMPARE(file.readLine().constData(), QByteArray("2\n").constData());
854 void tst_QFile::missingEndOfLine()
856 QFile file(SRCDIR "noendofline.txt");
857 QVERIFY(file.open(QFile::ReadOnly));
859 int nlines = 0;
860 while (!file.atEnd()) {
861 ++nlines;
862 file.readLine();
865 QCOMPARE(nlines, 3);
868 void tst_QFile::readBlock()
870 QFile f( SRCDIR "testfile.txt" );
871 f.open( QIODevice::ReadOnly );
873 int length = 0;
874 char p[256];
875 length = f.read( p, 256 );
876 f.close();
877 QCOMPARE( length, 245 );
878 QCOMPARE( p[59], 'D' );
879 QCOMPARE( p[178], 'T' );
880 QCOMPARE( p[199], 'l' );
883 void tst_QFile::getch()
885 QFile f( SRCDIR "testfile.txt" );
886 f.open( QIODevice::ReadOnly );
888 char c;
889 int i = 0;
890 while (f.getChar(&c)) {
891 QCOMPARE(f.pos(), qint64(i + 1));
892 if ( i == 59 )
893 QCOMPARE( c, 'D' );
894 ++i;
896 f.close();
897 QCOMPARE( i, 245 );
900 void tst_QFile::ungetChar()
902 QFile f(SRCDIR "testfile.txt");
903 QVERIFY(f.open(QIODevice::ReadOnly));
905 QByteArray array = f.readLine();
906 QCOMPARE(array.constData(), "----------------------------------------------------------\n");
907 f.ungetChar('\n');
909 array = f.readLine();
910 QCOMPARE(array.constData(), "\n");
912 f.ungetChar('\n');
913 f.ungetChar('-');
914 f.ungetChar('-');
916 array = f.readLine();
917 QCOMPARE(array.constData(), "--\n");
919 QFile::remove("genfile.txt");
920 QFile out("genfile.txt");
921 QVERIFY(out.open(QIODevice::ReadWrite));
922 out.write("123");
923 out.seek(0);
924 QCOMPARE(out.readAll().constData(), "123");
925 out.ungetChar('3');
926 out.write("4");
927 out.seek(0);
928 QCOMPARE(out.readAll().constData(), "124");
929 out.ungetChar('4');
930 out.ungetChar('2');
931 out.ungetChar('1');
932 char buf[3];
933 QCOMPARE(out.read(buf, sizeof(buf)), qint64(3));
934 QCOMPARE(buf[0], '1');
935 QCOMPARE(buf[1], '2');
936 QCOMPARE(buf[2], '4');
939 void tst_QFile::invalidFile_data()
941 QTest::addColumn<QString>("fileName");
942 #if !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN)
943 QTest::newRow( "x11" ) << QString( "qwe//" );
944 #else
945 QTest::newRow( "colon1" ) << QString( "fail:invalid" );
946 QTest::newRow( "colon2" ) << QString( "f:ail:invalid" );
947 QTest::newRow( "colon3" ) << QString( ":failinvalid" );
948 QTest::newRow( "forwardslash" ) << QString( "fail/invalid" );
949 QTest::newRow( "asterisk" ) << QString( "fail*invalid" );
950 QTest::newRow( "questionmark" ) << QString( "fail?invalid" );
951 QTest::newRow( "quote" ) << QString( "fail\"invalid" );
952 QTest::newRow( "lt" ) << QString( "fail<invalid" );
953 QTest::newRow( "gt" ) << QString( "fail>invalid" );
954 QTest::newRow( "pipe" ) << QString( "fail|invalid" );
955 #endif
958 void tst_QFile::invalidFile()
960 QFETCH( QString, fileName );
961 QFile f( fileName );
962 QVERIFY( !f.open( QIODevice::ReadWrite ) );
965 void tst_QFile::createFile()
967 if ( QFile::exists( "createme.txt" ) )
968 QFile::remove( "createme.txt" );
969 QVERIFY( !QFile::exists( "createme.txt" ) );
971 QFile f( "createme.txt" );
972 QVERIFY( f.open( QIODevice::WriteOnly ) );
973 f.close();
974 QVERIFY( QFile::exists( "createme.txt" ) );
977 void tst_QFile::append()
979 const QString name("appendme.txt");
980 if (QFile::exists(name))
981 QFile::remove(name);
982 QVERIFY(!QFile::exists(name));
984 QFile f(name);
985 QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
986 f.putChar('a');
987 f.close();
989 QVERIFY(f.open(QIODevice::Append));
990 QVERIFY(f.pos() == 1);
991 f.putChar('a');
992 f.close();
993 QCOMPARE(int(f.size()), 2);
996 void tst_QFile::permissions_data()
998 QTest::addColumn<QString>("file");
999 QTest::addColumn<uint>("perms");
1000 QTest::addColumn<bool>("expected");
1002 QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser) << true;
1003 QTest::newRow("data1") << SRCDIR "tst_qfile.cpp" << uint(QFile::ReadUser) << true;
1004 // QTest::newRow("data2") << "tst_qfile.cpp" << int(QFile::WriteUser) << false;
1005 QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ReadUser) << true;
1006 QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::WriteUser) << false;
1007 QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ExeUser) << false;
1010 void tst_QFile::permissions()
1012 #if defined(Q_OS_SYMBIAN)
1013 if (qstrcmp(QTest::currentDataTag(), "data0") == 0)
1014 QSKIP("Symbian does not have execution permissions", SkipSingle);
1015 #endif
1016 QFETCH(QString, file);
1017 QFETCH(uint, perms);
1018 QFETCH(bool, expected);
1019 QFile f(file);
1020 QCOMPARE(((f.permissions() & perms) == QFile::Permissions(perms)), expected);
1023 void tst_QFile::setPermissions()
1025 DEPENDS_ON( "permissions" ); //if that doesn't work...
1027 if ( QFile::exists( "createme.txt" ) )
1028 QFile::remove( "createme.txt" );
1029 QVERIFY( !QFile::exists( "createme.txt" ) );
1031 QFile f("createme.txt");
1032 QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
1033 f.putChar('a');
1034 f.close();
1036 QFile::Permissions perms(QFile::WriteUser | QFile::ReadUser);
1037 QVERIFY(f.setPermissions(perms));
1038 QVERIFY((f.permissions() & perms) == perms);
1042 void tst_QFile::copy()
1044 QFile::setPermissions("tst_qfile_copy.cpp", QFile::WriteUser);
1045 QFile::remove("tst_qfile_copy.cpp");
1046 QFile::remove("test2");
1047 QVERIFY(QFile::copy(SRCDIR "tst_qfile.cpp", "tst_qfile_copy.cpp"));
1048 QFile in1(SRCDIR "tst_qfile.cpp"), in2("tst_qfile_copy.cpp");
1049 QVERIFY(in1.open(QFile::ReadOnly));
1050 QVERIFY(in2.open(QFile::ReadOnly));
1051 QByteArray data1 = in1.readAll(), data2 = in2.readAll();
1052 QCOMPARE(data1, data2);
1053 QFile::remove( "main_copy.cpp" );
1055 QFile::copy(QDir::currentPath(), QDir::currentPath() + QLatin1String("/test2"));
1058 void tst_QFile::copyAfterFail()
1060 QFile file1("file-to-be-copied.txt");
1061 QFile file2("existing-file.txt");
1063 QVERIFY(file1.open(QIODevice::ReadWrite) && "(test-precondition)");
1064 QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)");
1065 file2.close();
1066 QVERIFY(!QFile::exists("copied-file-1.txt") && "(test-precondition)");
1067 QVERIFY(!QFile::exists("copied-file-2.txt") && "(test-precondition)");
1069 QVERIFY(!file1.copy("existing-file.txt"));
1070 QCOMPARE(file1.error(), QFile::CopyError);
1072 QVERIFY(file1.copy("copied-file-1.txt"));
1073 QVERIFY(!file1.isOpen());
1074 QCOMPARE(file1.error(), QFile::NoError);
1076 QVERIFY(!file1.copy("existing-file.txt"));
1077 QCOMPARE(file1.error(), QFile::CopyError);
1079 QVERIFY(file1.copy("copied-file-2.txt"));
1080 QVERIFY(!file1.isOpen());
1081 QCOMPARE(file1.error(), QFile::NoError);
1083 QVERIFY(QFile::exists("copied-file-1.txt"));
1084 QVERIFY(QFile::exists("copied-file-2.txt"));
1086 QVERIFY(QFile::remove("file-to-be-copied.txt") && "(test-cleanup)");
1087 QVERIFY(QFile::remove("existing-file.txt") && "(test-cleanup)");
1088 QVERIFY(QFile::remove("copied-file-1.txt") && "(test-cleanup)");
1089 QVERIFY(QFile::remove("copied-file-2.txt") && "(test-cleanup)");
1092 void tst_QFile::copyRemovesTemporaryFile() const
1094 const QString newName(QLatin1String("copyRemovesTemporaryFile"));
1095 QVERIFY(QFile::copy(SRCDIR "forCopying.txt", newName));
1097 QVERIFY(!QFile::exists(QLatin1String( SRCDIR "qt_temp.XXXXXX")));
1098 QVERIFY(QFile::remove(newName));
1101 void tst_QFile::copyShouldntOverwrite()
1103 // Copy should not overwrite existing files.
1104 QFile::remove("tst_qfile.cpy");
1105 QFile file(SRCDIR "tst_qfile.cpp");
1106 QVERIFY(file.copy("tst_qfile.cpy"));
1107 #if defined(Q_OS_SYMBIAN)
1108 bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteUser);
1109 #else
1110 bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteOther);
1111 #endif
1112 QVERIFY(ok);
1113 QVERIFY(!file.copy("tst_qfile.cpy"));
1114 QFile::remove("tst_qfile.cpy");
1117 void tst_QFile::copyFallback()
1119 // Using a resource file to trigger QFile::copy's fallback handling
1120 QFile file(":/copy-fallback.qrc");
1121 QFile::remove("file-copy-destination.txt");
1123 QVERIFY2(file.exists(), "test precondition");
1124 QVERIFY2(!QFile::exists("file-copy-destination.txt"), "test precondition");
1126 // Fallback copy of closed file.
1127 QVERIFY(file.copy("file-copy-destination.txt"));
1128 QVERIFY(QFile::exists("file-copy-destination.txt"));
1129 QVERIFY(!file.isOpen());
1131 // Need to reset permissions on Windows to be able to delete
1132 QVERIFY(QFile::setPermissions("file-copy-destination.txt",
1133 QFile::ReadOwner | QFile::WriteOwner));
1134 QVERIFY(QFile::remove("file-copy-destination.txt"));
1136 // Fallback copy of open file.
1137 QVERIFY(file.open(QIODevice::ReadOnly));
1138 QVERIFY(file.copy("file-copy-destination.txt"));
1139 QVERIFY(QFile::exists("file-copy-destination.txt"));
1140 QVERIFY(!file.isOpen());
1142 QFile::remove("file-copy-destination.txt");
1145 #ifdef Q_OS_WIN
1146 #include <objbase.h>
1147 #include <shlobj.h>
1148 #endif
1150 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1151 static QString getWorkingDirectoryForLink(const QString &linkFileName)
1153 bool neededCoInit = false;
1154 QString ret;
1156 IShellLink *psl;
1157 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
1158 if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
1159 neededCoInit = true;
1160 CoInitialize(NULL);
1161 hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
1164 if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
1165 IPersistFile *ppf;
1166 hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
1167 if (SUCCEEDED(hres)) {
1168 hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
1169 //The original path of the link is retrieved. If the file/folder
1170 //was moved, the return value still have the old path.
1171 if(SUCCEEDED(hres)) {
1172 wchar_t szGotPath[MAX_PATH];
1173 if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
1174 ret = QString::fromWCharArray(szGotPath);
1176 ppf->Release();
1178 psl->Release();
1181 if (neededCoInit) {
1182 CoUninitialize();
1185 return ret;
1187 #endif
1189 void tst_QFile::link()
1191 QFile::remove("myLink.lnk");
1192 QFileInfo info1("tst_qfile.cpp");
1193 QVERIFY(QFile::link("tst_qfile.cpp", "myLink.lnk"));
1194 QFileInfo info2("myLink.lnk");
1195 QVERIFY(info2.isSymLink());
1196 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1198 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1199 QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath());
1200 QCOMPARE(QDir::fromNativeSeparators(wd), info1.absolutePath());
1201 #endif
1202 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1205 void tst_QFile::linkToDir()
1207 #if defined(Q_OS_SYMBIAN)
1208 QSKIP("Symbian does not support linking to directories", SkipAll);
1209 #endif
1210 QFile::remove("myLinkToDir.lnk");
1211 QDir dir;
1212 dir.mkdir("myDir");
1213 QFileInfo info1("myDir");
1214 QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
1215 QFileInfo info2("myLinkToDir.lnk");
1216 #if !(defined Q_OS_HPUX && defined(__ia64))
1217 // absurd HP-UX filesystem bug on gravlaks - checking if a symlink
1218 // resolves or not alters the file system to make the broken symlink
1219 // later fail...
1220 QVERIFY(info2.isSymLink());
1221 #endif
1222 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1223 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1224 QFile::remove("myLinkToDir.lnk");
1225 dir.rmdir("myDir");
1228 void tst_QFile::absolutePathLinkToRelativePath()
1230 QFile::remove("myDir/test.txt");
1231 QFile::remove("myDir/myLink.lnk");
1232 QDir dir;
1233 dir.mkdir("myDir");
1234 QFile("myDir/test.txt").open(QFile::WriteOnly);
1236 #ifdef Q_OS_WIN
1237 QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk"));
1238 #else
1239 QVERIFY(QFile::link("myDir/test.txt", "myDir/myLink.lnk"));
1240 #endif
1241 QEXPECT_FAIL("", "Symlinking using relative paths is currently different on Windows and Unix/Symbian", Continue);
1242 QCOMPARE(QFileInfo(QFile(QFileInfo("myDir/myLink.lnk").absoluteFilePath()).symLinkTarget()).absoluteFilePath(),
1243 QFileInfo("myDir/test.txt").absoluteFilePath());
1245 QFile::remove("myDir/test.txt");
1246 QFile::remove("myDir/myLink.lnk");
1247 dir.rmdir("myDir");
1250 void tst_QFile::readBrokenLink()
1252 QFile::remove("myLink2.lnk");
1253 QFileInfo info1("file12");
1254 #if defined(Q_OS_SYMBIAN)
1255 // In Symbian can't link to nonexisting file directly, so create the file temporarily
1256 QFile tempFile("file12");
1257 tempFile.open(QIODevice::WriteOnly);
1258 tempFile.link("myLink2.lnk");
1259 tempFile.remove();
1260 #else
1261 QVERIFY(QFile::link("file12", "myLink2.lnk"));
1262 #endif
1263 QFileInfo info2("myLink2.lnk");
1264 QVERIFY(info2.isSymLink());
1265 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1266 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1268 #if !defined(Q_OS_SYMBIAN)
1269 QVERIFY(QFile::link("ole/..", "myLink2.lnk"));
1270 QCOMPARE(QFileInfo("myLink2.lnk").symLinkTarget(), QDir::currentPath());
1271 #endif
1274 void tst_QFile::readTextFile_data()
1276 QTest::addColumn<QByteArray>("in");
1277 QTest::addColumn<QByteArray>("out");
1279 QTest::newRow("empty") << QByteArray() << QByteArray();
1280 QTest::newRow("a") << QByteArray("a") << QByteArray("a");
1281 QTest::newRow("a\\rb") << QByteArray("a\rb") << QByteArray("ab");
1282 QTest::newRow("\\n") << QByteArray("\n") << QByteArray("\n");
1283 QTest::newRow("\\r\\n") << QByteArray("\r\n") << QByteArray("\n");
1284 QTest::newRow("\\r") << QByteArray("\r") << QByteArray();
1285 QTest::newRow("twolines") << QByteArray("Hello\r\nWorld\r\n") << QByteArray("Hello\nWorld\n");
1286 QTest::newRow("twolines no endline") << QByteArray("Hello\r\nWorld") << QByteArray("Hello\nWorld");
1289 void tst_QFile::readTextFile()
1291 QFETCH(QByteArray, in);
1292 QFETCH(QByteArray, out);
1294 QFile winfile("winfile.txt");
1295 QVERIFY(winfile.open(QFile::WriteOnly | QFile::Truncate));
1296 winfile.write(in);
1297 winfile.close();
1299 QVERIFY(winfile.open(QFile::ReadOnly));
1300 QCOMPARE(winfile.readAll(), in);
1301 winfile.close();
1303 QVERIFY(winfile.open(QFile::ReadOnly | QFile::Text));
1304 QCOMPARE(winfile.readAll(), out);
1307 void tst_QFile::readTextFile2()
1310 QFile file(SRCDIR "testlog.txt");
1311 QVERIFY(file.open(QIODevice::ReadOnly));
1312 file.read(4097);
1316 QFile file(SRCDIR "testlog.txt");
1317 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
1318 file.read(4097);
1322 void tst_QFile::writeTextFile_data()
1324 QTest::addColumn<QByteArray>("in");
1326 QTest::newRow("empty") << QByteArray();
1327 QTest::newRow("a") << QByteArray("a");
1328 QTest::newRow("a\\rb") << QByteArray("a\rb");
1329 QTest::newRow("\\n") << QByteArray("\n");
1330 QTest::newRow("\\r\\n") << QByteArray("\r\n");
1331 QTest::newRow("\\r") << QByteArray("\r");
1332 QTest::newRow("twolines crlf") << QByteArray("Hello\r\nWorld\r\n");
1333 QTest::newRow("twolines crlf no endline") << QByteArray("Hello\r\nWorld");
1334 QTest::newRow("twolines lf") << QByteArray("Hello\nWorld\n");
1335 QTest::newRow("twolines lf no endline") << QByteArray("Hello\nWorld");
1336 QTest::newRow("mixed") << QByteArray("this\nis\r\na\nmixed\r\nfile\n");
1339 void tst_QFile::writeTextFile()
1341 QFETCH(QByteArray, in);
1343 QFile file("textfile.txt");
1344 QVERIFY(file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text));
1345 QByteArray out = in;
1346 #ifdef Q_OS_WIN
1347 out.replace('\n', "\r\n");
1348 #endif
1349 QCOMPARE(file.write(in), qlonglong(in.size()));
1350 file.close();
1352 file.open(QFile::ReadOnly);
1353 QCOMPARE(file.readAll(), out);
1356 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1357 void tst_QFile::largeUncFileSupport()
1359 qint64 size = Q_INT64_C(8589934592);
1360 qint64 dataOffset = Q_INT64_C(8589914592);
1361 QByteArray knownData("LargeFile content at offset 8589914592");
1362 QString largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin");
1365 // 1) Native file handling.
1366 QFile file(largeFile);
1367 QCOMPARE(file.size(), size);
1368 QVERIFY(file.open(QIODevice::ReadOnly));
1369 QCOMPARE(file.size(), size);
1370 QVERIFY(file.seek(dataOffset));
1371 QCOMPARE(file.read(knownData.size()), knownData);
1374 // 2) stdlib file handling.
1375 #if _MSC_VER <= 1310
1376 QSKIP("platform SDK for MSVC 2003 does not support large files", SkipAll);
1377 #endif
1378 QFile file;
1379 FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
1380 QVERIFY(file.open(fh, QIODevice::ReadOnly));
1381 QCOMPARE(file.size(), size);
1382 QVERIFY(file.seek(dataOffset));
1383 QCOMPARE(file.read(knownData.size()), knownData);
1384 fclose(fh);
1387 // 3) stdio file handling.
1388 QFile file;
1389 FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
1390 int fd = int(_fileno(fh));
1391 QVERIFY(file.open(fd, QIODevice::ReadOnly));
1392 QCOMPARE(file.size(), size);
1393 QVERIFY(file.seek(dataOffset));
1394 QCOMPARE(file.read(knownData.size()), knownData);
1395 fclose(fh);
1398 #endif
1400 void tst_QFile::tailFile()
1402 QSKIP("File change notifications are so far unsupported.", SkipAll);
1404 QFile file("tail.txt");
1405 QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
1407 QFile tailFile("tail.txt");
1408 QVERIFY(tailFile.open(QFile::ReadOnly));
1409 tailFile.seek(file.size());
1411 QSignalSpy readSignal(&tailFile, SIGNAL(readyRead()));
1413 file.write("", 1);
1415 QTestEventLoop::instance().enterLoop(5);
1417 QVERIFY(!QTestEventLoop::instance().timeout());
1418 QCOMPARE(readSignal.count(), 1);
1421 void tst_QFile::flush()
1423 QString fileName("stdfile.txt");
1425 QFile::remove(fileName);
1428 QFile file(fileName);
1429 QVERIFY(file.open(QFile::WriteOnly));
1430 QCOMPARE(file.write("abc", 3),qint64(3));
1434 QFile file(fileName);
1435 QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
1436 QCOMPARE(file.pos(), qlonglong(3));
1437 QCOMPARE(file.write("def", 3), qlonglong(3));
1438 QCOMPARE(file.pos(), qlonglong(6));
1442 QFile file("stdfile.txt");
1443 QVERIFY(file.open(QFile::ReadOnly));
1444 QCOMPARE(file.readAll(), QByteArray("abcdef"));
1447 QFile::remove(fileName);
1450 void tst_QFile::bufferedRead()
1452 QFile::remove("stdfile.txt");
1454 QFile file("stdfile.txt");
1455 QVERIFY(file.open(QFile::WriteOnly));
1456 file.write("abcdef");
1457 file.close();
1459 #if defined(Q_OS_WINCE)
1460 FILE *stdFile = fopen((QCoreApplication::applicationDirPath() + "/stdfile.txt").toAscii() , "r");
1461 #else
1462 FILE *stdFile = fopen("stdfile.txt", "r");
1463 #endif
1464 QVERIFY(stdFile);
1465 char c;
1466 QCOMPARE(int(fread(&c, 1, 1, stdFile)), 1);
1467 QCOMPARE(c, 'a');
1468 QCOMPARE(int(ftell(stdFile)), 1);
1471 QFile file;
1472 QVERIFY(file.open(stdFile, QFile::ReadOnly));
1473 QCOMPARE(file.pos(), qlonglong(1));
1474 QCOMPARE(file.read(&c, 1), qlonglong(1));
1475 QCOMPARE(c, 'b');
1476 QCOMPARE(file.pos(), qlonglong(2));
1479 fclose(stdFile);
1482 void tst_QFile::isSequential()
1484 #if defined (Q_OS_WIN) || defined(Q_OS_SYMBIAN)
1485 QSKIP("Unix only test.", SkipAll);
1486 #endif
1488 QFile zero("/dev/null");
1489 QVERIFY(zero.open(QFile::ReadOnly));
1490 QVERIFY(zero.isSequential());
1493 void tst_QFile::encodeName()
1495 QCOMPARE(QFile::encodeName(QString::null), QByteArray());
1498 void tst_QFile::truncate()
1500 for (int i = 0; i < 2; ++i) {
1501 QFile file("truncate.txt");
1502 QVERIFY(file.open(QFile::WriteOnly));
1503 file.write(QByteArray(200, '@'));
1504 file.close();
1506 QVERIFY(file.open((i ? QFile::WriteOnly : QFile::ReadWrite) | QFile::Truncate));
1507 file.write(QByteArray(100, '$'));
1508 file.close();
1510 QVERIFY(file.open(QFile::ReadOnly));
1511 QCOMPARE(file.readAll(), QByteArray(100, '$'));
1515 void tst_QFile::seekToPos()
1518 QFile file("seekToPos.txt");
1519 QVERIFY(file.open(QFile::WriteOnly));
1520 file.write("a\r\nb\r\nc\r\n");
1521 file.flush();
1524 QFile file("seekToPos.txt");
1525 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1526 file.seek(1);
1527 char c;
1528 QVERIFY(file.getChar(&c));
1529 QCOMPARE(c, '\n');
1531 QCOMPARE(file.pos(), qint64(3));
1532 file.seek(file.pos());
1533 QCOMPARE(file.pos(), qint64(3));
1535 file.seek(1);
1536 file.seek(file.pos());
1537 QCOMPARE(file.pos(), qint64(1));
1542 void tst_QFile::FILEReadWrite()
1544 // Tests modifing a file. First creates it then reads in 4 bytes and then overwrites these
1545 // 4 bytes with new values. At the end check to see the file contains the new values.
1547 QFile::remove("FILEReadWrite.txt");
1549 // create test file
1551 QFile f("FILEReadWrite.txt");
1552 QVERIFY(f.open(QFile::WriteOnly));
1553 QDataStream ds(&f);
1554 qint8 c = 0;
1555 ds << c;
1556 c = 1;
1557 ds << c;
1558 c = 2;
1559 ds << c;
1560 c = 3;
1561 ds << c;
1562 c = 4;
1563 ds << c;
1564 c = 5;
1565 ds << c;
1566 c = 6;
1567 ds << c;
1568 c = 7;
1569 ds << c;
1570 c = 8;
1571 ds << c;
1572 c = 9;
1573 ds << c;
1574 c = 10;
1575 ds << c;
1576 c = 11;
1577 ds << c;
1578 f.close();
1581 #ifdef Q_OS_WINCE
1582 FILE *fp = fopen(qPrintable(QCoreApplication::applicationDirPath() + "\\FILEReadWrite.txt"), "r+b");
1583 #else
1584 FILE *fp = fopen("FILEReadWrite.txt", "r+b");
1585 #endif
1586 QVERIFY(fp);
1587 QFile file;
1588 QVERIFY(file.open(fp, QFile::ReadWrite));
1589 QDataStream sfile(&file) ;
1591 qint8 var1,var2,var3,var4;
1592 while (!sfile.atEnd())
1594 qint64 base = file.pos();
1596 QCOMPARE(file.pos(), base + 0);
1597 sfile >> var1;
1598 QCOMPARE(file.pos(), base + 1);
1599 file.flush(); // flushing should not change the base
1600 QCOMPARE(file.pos(), base + 1);
1601 sfile >> var2;
1602 QCOMPARE(file.pos(), base + 2);
1603 sfile >> var3;
1604 QCOMPARE(file.pos(), base + 3);
1605 sfile >> var4;
1606 QCOMPARE(file.pos(), base + 4);
1607 file.seek(file.pos() - 4) ; // Move it back 4, for we are going to write new values based on old ones
1608 QCOMPARE(file.pos(), base + 0);
1609 sfile << qint8(var1 + 5);
1610 QCOMPARE(file.pos(), base + 1);
1611 sfile << qint8(var2 + 5);
1612 QCOMPARE(file.pos(), base + 2);
1613 sfile << qint8(var3 + 5);
1614 QCOMPARE(file.pos(), base + 3);
1615 sfile << qint8(var4 + 5);
1616 QCOMPARE(file.pos(), base + 4);
1619 file.close();
1620 fclose(fp);
1622 // check modified file
1624 QFile f("FILEReadWrite.txt");
1625 QVERIFY(f.open(QFile::ReadOnly));
1626 QDataStream ds(&f);
1627 qint8 c = 0;
1628 ds >> c;
1629 QCOMPARE(c, (qint8)5);
1630 ds >> c;
1631 QCOMPARE(c, (qint8)6);
1632 ds >> c;
1633 QCOMPARE(c, (qint8)7);
1634 ds >> c;
1635 QCOMPARE(c, (qint8)8);
1636 ds >> c;
1637 QCOMPARE(c, (qint8)9);
1638 ds >> c;
1639 QCOMPARE(c, (qint8)10);
1640 ds >> c;
1641 QCOMPARE(c, (qint8)11);
1642 ds >> c;
1643 QCOMPARE(c, (qint8)12);
1644 ds >> c;
1645 QCOMPARE(c, (qint8)13);
1646 ds >> c;
1647 QCOMPARE(c, (qint8)14);
1648 ds >> c;
1649 QCOMPARE(c, (qint8)15);
1650 ds >> c;
1651 QCOMPARE(c, (qint8)16);
1652 f.close();
1655 QFile::remove("FILEReadWrite.txt");
1660 #include <qglobal.h>
1661 #define BUFFSIZE 1
1662 #define FILESIZE 0x10000000f
1663 void tst_QFile::largeFileSupport()
1665 #ifdef Q_OS_SOLARIS
1666 QSKIP("Solaris does not support statfs", SkipAll);
1667 #else
1668 qlonglong sizeNeeded = 2147483647;
1669 sizeNeeded *= 2;
1670 sizeNeeded += 1024;
1671 qlonglong freespace = qlonglong(0);
1672 #ifdef Q_WS_WIN
1673 _ULARGE_INTEGER free;
1674 if (::GetDiskFreeSpaceEx((wchar_t*)QDir::currentPath().utf16(), &free, 0, 0))
1675 freespace = free.QuadPart;
1676 if (freespace != 0) {
1677 #elif defined(Q_OS_IRIX)
1678 struct statfs info;
1679 if (statfs(QDir::currentPath().local8Bit(), &info, sizeof(struct statfs), 0) == 0) {
1680 freespace = qlonglong(info.f_bfree * info.f_bsize);
1681 #else
1682 struct statfs info;
1683 if (statfs(const_cast<char *>(QDir::currentPath().toLocal8Bit().constData()), &info) == 0) {
1684 freespace = qlonglong(info.f_bavail * info.f_bsize);
1685 #endif
1686 if (freespace > sizeNeeded) {
1687 QFile bigFile("bigfile");
1688 if (bigFile.open(QFile::ReadWrite)) {
1689 char c[BUFFSIZE] = {'a'};
1690 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
1691 qlonglong oldPos = bigFile.pos();
1692 QVERIFY(bigFile.resize(sizeNeeded));
1693 QCOMPARE(oldPos, bigFile.pos());
1694 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
1695 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
1697 bigFile.close();
1698 if (bigFile.open(QFile::ReadOnly)) {
1699 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
1700 int i = 0;
1701 for (i=0; i<BUFFSIZE; i++)
1702 QCOMPARE(c[i], 'a');
1703 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
1704 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
1705 for (i=0; i<BUFFSIZE; i++)
1706 QCOMPARE(c[i], 'a');
1707 bigFile.close();
1708 QVERIFY(bigFile.remove());
1709 } else {
1710 QVERIFY(bigFile.remove());
1711 QFAIL("Could not reopen file");
1713 } else {
1714 QFAIL("Could not open file");
1716 } else {
1717 QSKIP("Not enough space to run test", SkipSingle);
1719 } else {
1720 QFAIL("Could not determin disk space");
1722 #endif
1726 void tst_QFile::i18nFileName_data()
1728 QTest::addColumn<QString>("fileName");
1730 QTest::newRow( "01" ) << QString::fromUtf8("xxxxxxx.txt");
1733 void tst_QFile::i18nFileName()
1735 QFETCH(QString, fileName);
1736 if (QFile::exists(fileName)) {
1737 QVERIFY(QFile::remove(fileName));
1740 QFile file(fileName);
1741 QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
1742 QTextStream ts(&file);
1743 ts.setCodec("UTF-8");
1744 ts << fileName << endl;
1747 QFile file(fileName);
1748 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1749 QTextStream ts(&file);
1750 ts.setCodec("UTF-8");
1751 QString line = ts.readLine();
1752 QCOMPARE(line, fileName);
1754 QVERIFY(QFile::remove(fileName));
1758 void tst_QFile::longFileName_data()
1760 QTest::addColumn<QString>("fileName");
1762 QTest::newRow( "16 chars" ) << QString::fromLatin1("longFileName.txt");
1763 QTest::newRow( "52 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName.txt");
1764 QTest::newRow( "148 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1765 "longFileNamelongFileNamelongFileNamelongFileName"
1766 "longFileNamelongFileNamelongFileNamelongFileName.txt");
1767 QTest::newRow( "244 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1768 "longFileNamelongFileNamelongFileNamelongFileName"
1769 "longFileNamelongFileNamelongFileNamelongFileName"
1770 "longFileNamelongFileNamelongFileNamelongFileName"
1771 "longFileNamelongFileNamelongFileNamelongFileName.txt");
1772 QTest::newRow( "244 chars to absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1773 "longFileNamelongFileNamelongFileNamelongFileName"
1774 "longFileNamelongFileNamelongFileNamelongFileName"
1775 "longFileNamelongFileNamelongFileNamelongFileName"
1776 "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath();
1777 /* needs to be put on a windows 2000 > test machine
1778 QTest::newRow( "244 chars on UNC" ) << QString::fromLatin1("//arsia/D/troll/tmp/longFileNamelongFileNamelongFileNamelongFileName"
1779 "longFileNamelongFileNamelongFileNamelongFileName"
1780 "longFileNamelongFileNamelongFileNamelongFileName"
1781 "longFileNamelongFileNamelongFileNamelongFileName"
1782 "longFileNamelongFileNamelongFileNamelongFileName.txt");*/
1785 void tst_QFile::longFileName()
1787 QFETCH(QString, fileName);
1788 if (QFile::exists(fileName)) {
1789 QVERIFY(QFile::remove(fileName));
1792 QFile file(fileName);
1793 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
1794 QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
1795 QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
1796 #endif
1797 QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
1798 QTextStream ts(&file);
1799 ts << fileName << endl;
1802 QFile file(fileName);
1803 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1804 QTextStream ts(&file);
1805 QString line = ts.readLine();
1806 QCOMPARE(line, fileName);
1808 QString newName = fileName + QLatin1String("1");
1810 QVERIFY(QFile::copy(fileName, newName));
1811 QFile file(newName);
1812 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1813 QTextStream ts(&file);
1814 QString line = ts.readLine();
1815 QCOMPARE(line, fileName);
1818 QVERIFY(QFile::remove(newName));
1820 QVERIFY(QFile::rename(fileName, newName));
1821 QFile file(newName);
1822 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1823 QTextStream ts(&file);
1824 QString line = ts.readLine();
1825 QCOMPARE(line, fileName);
1827 QVERIFY(QFile::exists(newName));
1828 QVERIFY(QFile::remove(newName));
1831 class MyEngine : public QAbstractFileEngine
1833 public:
1834 MyEngine(int n) { number = n; }
1835 virtual ~MyEngine() {}
1837 void setFileName(const QString &) {}
1838 bool open(int ) { return false; }
1839 bool close() { return false; }
1840 bool flush() { return false; }
1841 qint64 size() const { return 123 + number; }
1842 qint64 at() const { return -1; }
1843 bool seek(qint64) { return false; }
1844 bool isSequential() const { return false; }
1845 qint64 read(char *, qint64) { return -1; }
1846 qint64 write(const char *, qint64) { return -1; }
1847 bool remove() { return false; }
1848 bool copy(const QString &) { return false; }
1849 bool rename(const QString &) { return false; }
1850 bool link(const QString &) { return false; }
1851 bool mkdir(const QString &, bool) const { return false; }
1852 bool rmdir(const QString &, bool) const { return false; }
1853 bool setSize(qint64) { return false; }
1854 QStringList entryList(QDir::Filters, const QStringList &) const { return QStringList(); }
1855 bool caseSensitive() const { return false; }
1856 bool isRelativePath() const { return false; }
1857 FileFlags fileFlags(FileFlags) const { return 0; }
1858 bool chmod(uint) { return false; }
1859 QString fileName(FileName) const { return name; }
1860 uint ownerId(FileOwner) const { return 0; }
1861 QString owner(FileOwner) const { return QString(); }
1862 QDateTime fileTime(FileTime) const { return QDateTime(); }
1864 private:
1865 int number;
1866 QString name;
1869 class MyHandler : public QAbstractFileEngineHandler
1871 public:
1872 inline QAbstractFileEngine *create(const QString &) const
1874 return new MyEngine(1);
1878 class MyHandler2 : public QAbstractFileEngineHandler
1880 public:
1881 inline QAbstractFileEngine *create(const QString &) const
1883 return new MyEngine(2);
1887 void tst_QFile::fileEngineHandler()
1889 // A file that does not exist has a size of 0.
1890 QFile::remove("ole.bull");
1891 QFile file("ole.bull");
1892 QCOMPARE(file.size(), qint64(0));
1894 // Instantiating our handler will enable the new engine.
1895 MyHandler handler;
1896 file.setFileName("ole.bull");
1897 QCOMPARE(file.size(), qint64(124));
1899 // A new, identical handler should take preference over the last one.
1900 MyHandler2 handler2;
1901 file.setFileName("ole.bull");
1902 QCOMPARE(file.size(), qint64(125));
1906 class MyRecursiveHandler : public QAbstractFileEngineHandler
1908 public:
1909 inline QAbstractFileEngine *create(const QString &fileName) const
1911 if (fileName.startsWith(":!")) {
1912 QDir dir;
1913 QString realFile = SRCDIR + fileName.mid(2);
1914 if (dir.exists(realFile))
1915 return new QFSFileEngine(realFile);
1917 return 0;
1921 void tst_QFile::useQFileInAFileHandler()
1923 // This test should not dead-lock
1924 MyRecursiveHandler handler;
1925 QFile file(":!tst_qfile.cpp");
1926 QVERIFY(file.exists());
1929 void tst_QFile::getCharFF()
1931 QFile file("file.txt");
1932 file.open(QFile::ReadWrite);
1933 file.write("\xff\xff\xff");
1934 file.flush();
1935 file.seek(0);
1937 char c;
1938 QVERIFY(file.getChar(&c));
1939 QVERIFY(file.getChar(&c));
1940 QVERIFY(file.getChar(&c));
1943 void tst_QFile::remove_and_exists()
1945 QFile::remove("tull_i_grunn.txt");
1946 QFile f("tull_i_grunn.txt");
1948 QVERIFY(!f.exists());
1950 bool opened = f.open(QIODevice::WriteOnly);
1951 QVERIFY(opened);
1953 f.write(QString("testing that remove/exists work...").toLatin1());
1954 f.close();
1956 QVERIFY(f.exists());
1958 f.remove();
1959 QVERIFY(!f.exists());
1962 void tst_QFile::removeOpenFile()
1965 // remove an opened, write-only file
1966 QFile::remove("remove_unclosed.txt");
1967 QFile f("remove_unclosed.txt");
1969 QVERIFY(!f.exists());
1970 bool opened = f.open(QIODevice::WriteOnly);
1971 QVERIFY(opened);
1972 f.write(QString("testing that remove closes the file first...").toLatin1());
1974 bool removed = f.remove(); // remove should both close and remove the file
1975 QVERIFY(removed);
1976 QVERIFY(!f.isOpen());
1977 QVERIFY(!f.exists());
1978 QVERIFY(f.error() == QFile::NoError);
1982 // remove an opened, read-only file
1983 QFile::remove("remove_unclosed.txt");
1985 // first, write a file that we can remove
1987 QFile f("remove_unclosed.txt");
1988 QVERIFY(!f.exists());
1989 bool opened = f.open(QIODevice::WriteOnly);
1990 QVERIFY(opened);
1991 f.write(QString("testing that remove closes the file first...").toLatin1());
1992 f.close();
1995 QFile f("remove_unclosed.txt");
1996 bool opened = f.open(QIODevice::ReadOnly);
1997 QVERIFY(opened);
1998 f.readAll();
1999 // this used to only fail on FreeBSD (and Mac OS X)
2000 QVERIFY(f.flush());
2001 bool removed = f.remove(); // remove should both close and remove the file
2002 QVERIFY(removed);
2003 QVERIFY(!f.isOpen());
2004 QVERIFY(!f.exists());
2005 QVERIFY(f.error() == QFile::NoError);
2009 void tst_QFile::fullDisk()
2011 QFile file("/dev/full");
2012 if (!file.exists())
2013 QSKIP("/dev/full doesn't exist on this system", SkipAll);
2015 QVERIFY(file.open(QIODevice::WriteOnly));
2016 file.write("foobar", 6);
2018 QVERIFY(!file.flush());
2019 QCOMPARE(file.error(), QFile::ResourceError);
2020 QVERIFY(!file.flush());
2021 QCOMPARE(file.error(), QFile::ResourceError);
2023 char c = 0;
2024 file.write(&c, 0);
2025 QVERIFY(!file.flush());
2026 QCOMPARE(file.error(), QFile::ResourceError);
2027 file.write(&c, 1);
2028 QVERIFY(!file.flush());
2029 QCOMPARE(file.error(), QFile::ResourceError);
2031 file.close();
2032 QVERIFY(!file.isOpen());
2033 QCOMPARE(file.error(), QFile::ResourceError);
2034 file.open(QIODevice::WriteOnly);
2035 QCOMPARE(file.error(), QFile::NoError);
2036 file.close();
2037 QCOMPARE(file.error(), QFile::NoError);
2039 // try again without flush:
2040 QVERIFY(file.open(QIODevice::WriteOnly));
2041 file.write("foobar", 6);
2042 file.close();
2043 QVERIFY(file.error() != QFile::NoError);
2046 void tst_QFile::writeLargeDataBlock_data()
2048 QTest::addColumn<QString>("fileName");
2049 QTest::addColumn<int>("type");
2051 QTest::newRow("localfile-QFile") << "./largeblockfile.txt" << (int)OpenQFile;
2052 QTest::newRow("localfile-Fd") << "./largeblockfile.txt" << (int)OpenFd;
2053 QTest::newRow("localfile-Stream") << "./largeblockfile.txt" << (int)OpenStream;
2055 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2056 // Some semi-randomness to avoid collisions.
2057 QTest::newRow("unc file")
2058 << QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
2059 .arg(QHostInfo::localHostName())
2060 .arg(QTime::currentTime().msec()) << (int)OpenQFile;
2061 #endif
2064 static QByteArray getLargeDataBlock()
2066 static QByteArray array;
2068 if (array.isNull())
2070 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
2071 int resizeSize = 1024 * 1024; // WinCE and Symbian do not have much space
2072 #else
2073 int resizeSize = 64 * 1024 * 1024;
2074 #endif
2075 array.resize(resizeSize);
2076 for (int i = 0; i < array.size(); ++i)
2077 array[i] = uchar(i);
2080 return array;
2083 void tst_QFile::writeLargeDataBlock()
2085 QFETCH(QString, fileName);
2086 QFETCH( int, type );
2088 QByteArray const originalData = getLargeDataBlock();
2091 QFile file(fileName);
2093 QVERIFY2( openFile(file, QIODevice::WriteOnly, (FileType)type),
2094 qPrintable(QString("Couldn't open file for writing: [%1]").arg(fileName)) );
2095 QCOMPARE( file.write(originalData), (qint64)originalData.size() );
2096 QVERIFY( file.flush() );
2098 closeFile(file);
2101 QByteArray readData;
2104 QFile file(fileName);
2106 QVERIFY2( openFile(file, QIODevice::ReadOnly, (FileType)type),
2107 qPrintable(QString("Couldn't open file for reading: [%1]").arg(fileName)) );
2108 readData = file.readAll();
2109 closeFile(file);
2112 QCOMPARE( readData, originalData );
2113 QVERIFY( QFile::remove(fileName) );
2116 void tst_QFile::readFromWriteOnlyFile()
2118 QFile file("writeonlyfile");
2119 QVERIFY(file.open(QFile::WriteOnly));
2120 char c;
2121 QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device");
2122 QCOMPARE(file.read(&c, 1), qint64(-1));
2125 void tst_QFile::writeToReadOnlyFile()
2127 QFile file("readonlyfile");
2128 QVERIFY(file.open(QFile::ReadOnly));
2129 char c = 0;
2130 QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device");
2131 QCOMPARE(file.write(&c, 1), qint64(-1));
2134 void tst_QFile::virtualFile()
2136 // test if QFile works with virtual files
2137 QString fname;
2138 #if defined(Q_OS_LINUX)
2139 fname = "/proc/self/maps";
2140 #elif defined(Q_OS_AIX)
2141 fname = QString("/proc/%1/map").arg(getpid());
2142 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
2143 fname = "/proc/curproc/map";
2144 #else
2145 QSKIP("This platform does not have 0-sized virtual files", SkipAll);
2146 #endif
2148 // consistency check
2149 QFileInfo fi(fname);
2150 QVERIFY(fi.exists());
2151 QVERIFY(fi.isFile());
2152 QCOMPARE(fi.size(), Q_INT64_C(0));
2154 // open the file
2155 QFile f(fname);
2156 QVERIFY(f.open(QIODevice::ReadOnly));
2157 QCOMPARE(f.size(), Q_INT64_C(0));
2158 QVERIFY(f.atEnd());
2160 // read data
2161 QByteArray data = f.read(16);
2162 QCOMPARE(data.size(), 16);
2163 QCOMPARE(f.pos(), Q_INT64_C(16));
2165 // line-reading
2166 data = f.readLine();
2167 QVERIFY(!data.isEmpty());
2169 // read all:
2170 data = f.readAll();
2171 QVERIFY(f.pos() != 0);
2172 QVERIFY(!data.isEmpty());
2174 // seeking
2175 QVERIFY(f.seek(1));
2176 QCOMPARE(f.pos(), Q_INT64_C(1));
2179 void tst_QFile::textFile()
2181 #if defined(Q_OS_WINCE)
2182 FILE *fs = ::fopen((QCoreApplication::applicationDirPath() + "/writeabletextfile").toAscii() , "wt");
2183 #elif defined(Q_OS_WIN)
2184 FILE *fs = ::fopen("writeabletextfile", "wt");
2185 #else
2186 FILE *fs = ::fopen("writeabletextfile", "w");
2187 #endif
2188 QFile f;
2189 QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n");
2190 QByteArray part2("Add\nsome\nmore\nnewlines\n");
2192 QVERIFY(f.open(fs, QIODevice::WriteOnly));
2193 f.write(part1);
2194 f.write(part2);
2195 f.close();
2196 ::fclose(fs);
2198 QFile file("writeabletextfile");
2199 QVERIFY(file.open(QIODevice::ReadOnly));
2201 QByteArray data = file.readAll();
2203 QByteArray expected = part1 + part2;
2204 #ifdef Q_OS_WIN
2205 expected.replace("\n", "\015\012");
2206 #endif
2207 QCOMPARE(data, expected);
2208 file.close();
2209 file.remove();
2212 void tst_QFile::rename_data()
2214 QTest::addColumn<QString>("source");
2215 QTest::addColumn<QString>("destination");
2216 QTest::addColumn<bool>("result");
2218 QTest::newRow("a -> b") << QString("a") << QString("b") << false;
2219 QTest::newRow("a -> .") << QString("a") << QString(".") << false;
2220 QTest::newRow("renamefile -> renamefile") << QString("renamefile") << QString("renamefile") << false;
2221 QTest::newRow("renamefile -> Makefile") << QString("renamefile") << QString("Makefile") << false;
2222 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
2223 QTest::newRow("renamefile -> /etc/renamefile") << QString("renamefile") << QString("/etc/renamefile") << false;
2224 #endif
2225 QTest::newRow("renamefile -> renamedfile") << QString("renamefile") << QString("renamedfile") << true;
2226 QTest::newRow("renamefile -> ..") << QString("renamefile") << QString("..") << false;
2229 void tst_QFile::rename()
2231 QFETCH(QString, source);
2232 QFETCH(QString, destination);
2233 QFETCH(bool, result);
2235 QFile::remove("renamedfile");
2236 QFile f("renamefile");
2237 f.open(QFile::WriteOnly);
2238 f.close();
2240 QFile file(source);
2241 QCOMPARE(file.rename(destination), result);
2242 if (result)
2243 QCOMPARE(file.error(), QFile::NoError);
2244 else
2245 QCOMPARE(file.error(), QFile::RenameError);
2247 QFile::remove("renamefile");
2251 \since 4.5
2253 Some special files have QFile::atEnd() returning true, even though there is
2254 more data available. True for corner cases, as well as some mounts on OS X.
2256 Here, we reproduce that condition by having a QFile sub-class with this
2257 peculiar atEnd() behavior.
2259 See task 231583.
2261 void tst_QFile::renameWithAtEndSpecialFile() const
2263 class PeculiarAtEnd : public QFile
2265 public:
2266 virtual bool atEnd() const
2268 return true;
2272 const QString newName(QLatin1String("newName.txt"));
2273 /* Cleanup, so we're a bit more robust. */
2274 QFile::remove(newName);
2276 const QString originalName(QString(SRCDIR "forRenaming.txt"));
2278 PeculiarAtEnd file;
2279 file.setFileName(originalName);
2280 QVERIFY(file.open(QIODevice::ReadOnly));
2282 QVERIFY(file.rename(newName));
2284 file.close();
2285 /* Guess what, we have to rename it back, otherwise we'll fail on second
2286 * invocation. */
2287 QVERIFY(QFile::rename(newName, originalName));
2290 void tst_QFile::renameFallback()
2292 // Using a resource file both to trigger QFile::rename's fallback handling
2293 // and as a *read-only* source whose move should fail.
2294 QFile file(":/rename-fallback.qrc");
2295 QVERIFY(file.exists() && "(test-precondition)");
2296 QFile::remove("file-rename-destination.txt");
2298 QVERIFY(!file.rename("file-rename-destination.txt"));
2299 QVERIFY(!QFile::exists("file-rename-destination.txt"));
2300 QVERIFY(!file.isOpen());
2303 void tst_QFile::renameMultiple()
2305 // create the file if it doesn't exist
2306 QFile file("file-to-be-renamed.txt");
2307 QFile file2("existing-file.txt");
2308 QVERIFY(file.open(QIODevice::ReadWrite) && "(test-precondition)");
2309 QVERIFY(file2.open(QIODevice::ReadWrite) && "(test-precondition)");
2311 // any stale files from previous test failures?
2312 QFile::remove("file-renamed-once.txt");
2313 QFile::remove("file-renamed-twice.txt");
2315 // begin testing
2316 QVERIFY(QFile::exists("existing-file.txt"));
2317 QVERIFY(!file.rename("existing-file.txt"));
2318 QCOMPARE(file.error(), QFile::RenameError);
2319 QCOMPARE(file.fileName(), QString("file-to-be-renamed.txt"));
2321 QVERIFY(file.rename("file-renamed-once.txt"));
2322 QVERIFY(!file.isOpen());
2323 QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
2325 QVERIFY(QFile::exists("existing-file.txt"));
2326 QVERIFY(!file.rename("existing-file.txt"));
2327 QCOMPARE(file.error(), QFile::RenameError);
2328 QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
2330 QVERIFY(file.rename("file-renamed-twice.txt"));
2331 QVERIFY(!file.isOpen());
2332 QCOMPARE(file.fileName(), QString("file-renamed-twice.txt"));
2334 QVERIFY(QFile::exists("existing-file.txt"));
2335 QVERIFY(!QFile::exists("file-to-be-renamed.txt"));
2336 QVERIFY(!QFile::exists("file-renamed-once.txt"));
2337 QVERIFY(QFile::exists("file-renamed-twice.txt"));
2339 file.remove();
2340 file2.remove();
2341 QVERIFY(!QFile::exists("file-renamed-twice.txt"));
2342 QVERIFY(!QFile::exists("existing-file.txt"));
2345 void tst_QFile::appendAndRead()
2347 QFile writeFile(QLatin1String("appendfile.txt"));
2348 QVERIFY(writeFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
2350 QFile readFile(QLatin1String("appendfile.txt"));
2351 QVERIFY(readFile.open(QIODevice::ReadOnly));
2353 // Write to the end of the file, then read that character back, and so on.
2354 for (int i = 0; i < 100; ++i) {
2355 char c = '\0';
2356 writeFile.putChar(char(i % 256));
2357 writeFile.flush();
2358 QVERIFY(readFile.getChar(&c));
2359 QCOMPARE(c, char(i % 256));
2360 QCOMPARE(readFile.pos(), writeFile.pos());
2363 // Write blocks and read them back
2364 for (int j = 0; j < 18; ++j) {
2365 writeFile.write(QByteArray(1 << j, '@'));
2366 writeFile.flush();
2367 QCOMPARE(readFile.read(1 << j).size(), 1 << j);
2370 QFile::remove(QLatin1String("appendfile.txt"));
2373 void tst_QFile::miscWithUncPathAsCurrentDir()
2375 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2376 QString current = QDir::currentPath();
2377 QVERIFY(QDir::setCurrent("//" + QtNetworkSettings::winServerName() + "/testsharewritable"));
2378 QFile file("test.pri");
2379 QVERIFY(file.exists());
2380 QCOMPARE(int(file.size()), 34);
2381 QVERIFY(file.open(QIODevice::ReadOnly));
2382 QVERIFY(QDir::setCurrent(current));
2383 #endif
2386 void tst_QFile::standarderror()
2388 QFile f;
2389 bool ok = f.open(stderr, QFile::WriteOnly);
2390 QVERIFY(ok);
2391 f.close();
2394 void tst_QFile::handle()
2396 #ifndef Q_OS_WINCE
2397 QFile file(SRCDIR "tst_qfile.cpp");
2398 QVERIFY(file.open(QIODevice::ReadOnly));
2399 int fd = int(file.handle());
2400 QVERIFY(fd > 2);
2401 QCOMPARE(int(file.handle()), fd);
2402 char c = '\0';
2403 QT_READ(int(file.handle()), &c, 1);
2404 QCOMPARE(c, '/');
2406 // test if the QFile and the handle remain in sync
2407 QVERIFY(file.getChar(&c));
2408 QCOMPARE(c, '*');
2410 // same, but read from QFile first now
2411 file.close();
2412 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
2413 fd = int(file.handle());
2414 QVERIFY(fd > 2);
2415 QVERIFY(file.getChar(&c));
2416 QCOMPARE(c, '/');
2417 #ifdef Q_OS_UNIX
2418 QCOMPARE(QT_READ(fd, &c, 1), ssize_t(1));
2419 #else
2420 QCOMPARE(QT_READ(fd, &c, 1), 1);
2421 #endif
2423 QCOMPARE(c, '*');
2424 #endif
2426 QFile file2;
2427 FILE *fp = fopen(SRCDIR "tst_qfile.cpp", "r");
2428 file2.open(fp, QIODevice::ReadOnly);
2429 QCOMPARE(int(file2.handle()), int(fileno(fp)));
2430 QCOMPARE(int(file2.handle()), int(fileno(fp)));
2431 fclose(fp);
2433 #ifdef Q_OS_UNIX
2434 QFile file3;
2435 fd = QT_OPEN(SRCDIR "tst_qfile.cpp", QT_OPEN_RDONLY);
2436 file3.open(fd, QIODevice::ReadOnly);
2437 QCOMPARE(int(file3.handle()), fd);
2438 QT_CLOSE(fd);
2439 #endif
2442 void tst_QFile::readEof_data()
2444 QTest::addColumn<QString>("filename");
2445 QTest::addColumn<int>("imode");
2447 QTest::newRow("buffered") << SRCDIR "testfile.txt" << 0;
2448 QTest::newRow("unbuffered") << SRCDIR "testfile.txt" << int(QIODevice::Unbuffered);
2450 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
2451 QTest::newRow("sequential,buffered") << "/dev/null" << 0;
2452 QTest::newRow("sequential,unbuffered") << "/dev/null" << int(QIODevice::Unbuffered);
2453 #endif
2456 void tst_QFile::readEof()
2458 QFETCH(QString, filename);
2459 QFETCH(int, imode);
2460 QIODevice::OpenMode mode = QIODevice::OpenMode(imode);
2463 QFile file(filename);
2464 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2465 bool isSequential = file.isSequential();
2466 if (!isSequential) {
2467 QVERIFY(file.seek(245));
2468 QVERIFY(file.atEnd());
2471 char buf[10];
2472 int ret = file.read(buf, sizeof buf);
2473 QCOMPARE(ret, 0);
2474 QVERIFY(file.error() == QFile::NoError);
2475 QVERIFY(file.atEnd());
2477 // Do it again to ensure that we get the same result
2478 ret = file.read(buf, sizeof buf);
2479 QCOMPARE(ret, 0);
2480 QVERIFY(file.error() == QFile::NoError);
2481 QVERIFY(file.atEnd());
2485 QFile file(filename);
2486 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2487 bool isSequential = file.isSequential();
2488 if (!isSequential) {
2489 QVERIFY(file.seek(245));
2490 QVERIFY(file.atEnd());
2493 QByteArray ret = file.read(10);
2494 QVERIFY(ret.isEmpty());
2495 QVERIFY(file.error() == QFile::NoError);
2496 QVERIFY(file.atEnd());
2498 // Do it again to ensure that we get the same result
2499 ret = file.read(10);
2500 QVERIFY(ret.isEmpty());
2501 QVERIFY(file.error() == QFile::NoError);
2502 QVERIFY(file.atEnd());
2506 QFile file(filename);
2507 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2508 bool isSequential = file.isSequential();
2509 if (!isSequential) {
2510 QVERIFY(file.seek(245));
2511 QVERIFY(file.atEnd());
2514 char buf[10];
2515 int ret = file.readLine(buf, sizeof buf);
2516 QCOMPARE(ret, -1);
2517 QVERIFY(file.error() == QFile::NoError);
2518 QVERIFY(file.atEnd());
2520 // Do it again to ensure that we get the same result
2521 ret = file.readLine(buf, sizeof buf);
2522 QCOMPARE(ret, -1);
2523 QVERIFY(file.error() == QFile::NoError);
2524 QVERIFY(file.atEnd());
2528 QFile file(filename);
2529 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2530 bool isSequential = file.isSequential();
2531 if (!isSequential) {
2532 QVERIFY(file.seek(245));
2533 QVERIFY(file.atEnd());
2536 QByteArray ret = file.readLine();
2537 QVERIFY(ret.isNull());
2538 QVERIFY(file.error() == QFile::NoError);
2539 QVERIFY(file.atEnd());
2541 // Do it again to ensure that we get the same result
2542 ret = file.readLine();
2543 QVERIFY(ret.isNull());
2544 QVERIFY(file.error() == QFile::NoError);
2545 QVERIFY(file.atEnd());
2549 QFile file(filename);
2550 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2551 bool isSequential = file.isSequential();
2552 if (!isSequential) {
2553 QVERIFY(file.seek(245));
2554 QVERIFY(file.atEnd());
2557 char c;
2558 QVERIFY(!file.getChar(&c));
2559 QVERIFY(file.error() == QFile::NoError);
2560 QVERIFY(file.atEnd());
2562 // Do it again to ensure that we get the same result
2563 QVERIFY(!file.getChar(&c));
2564 QVERIFY(file.error() == QFile::NoError);
2565 QVERIFY(file.atEnd());
2569 void tst_QFile::task167217()
2571 // Regression introduced in 4.3.0; after a failed stat, pos() could no
2572 // longer be calculated correctly.
2573 QFile::remove("tmp.txt");
2574 QFile file("tmp.txt");
2575 QVERIFY(!file.exists());
2576 QVERIFY(file.open(QIODevice::Append));
2577 QVERIFY(file.exists());
2578 file.write("qt430", 5);
2579 QVERIFY(!file.isSequential());
2580 QCOMPARE(file.pos(), qint64(5));
2581 file.remove();
2584 #define FILESIZE 65536 * 3
2586 void tst_QFile::map_data()
2588 QTest::addColumn<int>("fileSize");
2589 QTest::addColumn<int>("offset");
2590 QTest::addColumn<int>("size");
2591 QTest::addColumn<QFile::FileError>("error");
2593 QTest::newRow("zero") << FILESIZE << 0 << FILESIZE << QFile::NoError;
2594 QTest::newRow("small, but 0") << FILESIZE << 30 << FILESIZE - 30 << QFile::NoError;
2595 QTest::newRow("a page") << FILESIZE << 4096 << FILESIZE - 4096 << QFile::NoError;
2596 QTest::newRow("+page") << FILESIZE << 5000 << FILESIZE - 5000 << QFile::NoError;
2597 QTest::newRow("++page") << FILESIZE << 65576 << FILESIZE - 65576 << QFile::NoError;
2598 QTest::newRow("bad size") << FILESIZE << 0 << -1 << QFile::ResourceError;
2599 QTest::newRow("bad offset") << FILESIZE << -1 << 1 << QFile::UnspecifiedError;
2600 QTest::newRow("zerozero") << FILESIZE << 0 << 0 << QFile::UnspecifiedError;
2603 void tst_QFile::map()
2605 QFETCH(int, fileSize);
2606 QFETCH(int, offset);
2607 QFETCH(int, size);
2608 QFETCH(QFile::FileError, error);
2610 QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
2611 if (QFile::exists(fileName)) {
2612 QVERIFY(QFile::setPermissions(fileName,
2613 QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
2614 QFile::remove(fileName);
2616 QFile file(fileName);
2618 // invalid, not open
2619 uchar *memory = file.map(0, size);
2620 QVERIFY(!memory);
2621 QCOMPARE(file.error(), QFile::PermissionsError);
2622 QVERIFY(!file.unmap(memory));
2623 QCOMPARE(file.error(), QFile::PermissionsError);
2625 // make a file
2626 QVERIFY(file.open(QFile::ReadWrite));
2627 QVERIFY(file.resize(fileSize));
2628 QVERIFY(file.flush());
2629 file.close();
2630 QVERIFY(file.open(QFile::ReadWrite));
2631 memory = file.map(offset, size);
2632 if (error != QFile::NoError) {
2634 QVERIFY(file.error() != QFile::NoError);
2635 return;
2638 QCOMPARE(file.error(), error);
2639 QVERIFY(memory);
2640 memory[0] = 'Q';
2641 QVERIFY(file.unmap(memory));
2642 QCOMPARE(file.error(), QFile::NoError);
2644 // Verify changes were saved
2645 memory = file.map(offset, size);
2646 QCOMPARE(file.error(), QFile::NoError);
2647 QVERIFY(memory);
2648 QVERIFY(memory[0] == 'Q');
2649 QVERIFY(file.unmap(memory));
2650 QCOMPARE(file.error(), QFile::NoError);
2652 // hpux wont let you map multiple times.
2653 #if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API)
2654 // exotic test to make sure that multiple maps work
2655 uchar *memory1 = file.map(0, file.size());
2656 QCOMPARE(file.error(), QFile::NoError);
2657 uchar *memory2 = file.map(0, file.size());
2658 QCOMPARE(file.error(), QFile::NoError);
2659 QVERIFY(memory1);
2660 QVERIFY(memory2);
2661 QVERIFY(file.unmap(memory1));
2662 QCOMPARE(file.error(), QFile::NoError);
2663 QVERIFY(file.unmap(memory2));
2664 QCOMPARE(file.error(), QFile::NoError);
2665 memory1 = file.map(0, file.size());
2666 QCOMPARE(file.error(), QFile::NoError);
2667 QVERIFY(memory1);
2668 QVERIFY(file.unmap(memory1));
2669 QCOMPARE(file.error(), QFile::NoError);
2670 #endif
2672 file.close();
2674 #if defined(Q_OS_SYMBIAN)
2675 if (false) // No permissions for user makes no sense in Symbian
2676 #elif defined(Q_OS_UNIX)
2677 if (::getuid() != 0)
2678 // root always has permissions
2679 #endif
2681 // Change permissions on a file, just to confirm it would fail
2682 QFile::Permissions originalPermissions = file.permissions();
2683 QVERIFY(file.setPermissions(QFile::ReadOther));
2684 QVERIFY(!file.open(QFile::ReadWrite));
2685 memory = file.map(offset, size);
2686 QCOMPARE(file.error(), QFile::PermissionsError);
2687 QVERIFY(!memory);
2688 QVERIFY(file.setPermissions(originalPermissions));
2691 QVERIFY(file.remove());
2694 void tst_QFile::mapResource_data()
2696 QTest::addColumn<int>("offset");
2697 QTest::addColumn<int>("size");
2698 QTest::addColumn<QFile::FileError>("error");
2699 QTest::addColumn<QString>("fileName");
2701 QString validFile = ":/tst_qfileinfo/resources/file1.ext1";
2702 QString invalidFile = ":/tst_qfileinfo/resources/filefoo.ext1";
2704 for (int i = 0; i < 2; ++i) {
2705 QString file = (i == 0) ? validFile : invalidFile;
2706 QTest::newRow("0, 0") << 0 << 0 << QFile::UnspecifiedError << file;
2707 QTest::newRow("0, BIG") << 0 << 4096 << QFile::UnspecifiedError << file;
2708 QTest::newRow("-1, 0") << -1 << 0 << QFile::UnspecifiedError << file;
2709 QTest::newRow("0, -1") << 0 << -1 << QFile::UnspecifiedError << file;
2712 QTest::newRow("0, 1") << 0 << 1 << QFile::NoError << validFile;
2715 void tst_QFile::mapResource()
2717 QFETCH(QString, fileName);
2718 QFETCH(int, offset);
2719 QFETCH(int, size);
2720 QFETCH(QFile::FileError, error);
2722 QFile file(fileName);
2723 uchar *memory = file.map(offset, size);
2724 QCOMPARE(file.error(), error);
2725 QVERIFY((error == QFile::NoError) ? (memory != 0) : (memory == 0));
2726 if (error == QFile::NoError)
2727 QCOMPARE(QString(memory[0]), QString::number(offset + 1));
2728 QVERIFY(file.unmap(memory));
2731 void tst_QFile::mapOpenMode_data()
2733 QTest::addColumn<int>("openMode");
2735 QTest::newRow("ReadOnly") << int(QIODevice::ReadOnly);
2736 //QTest::newRow("WriteOnly") << int(QIODevice::WriteOnly); // this doesn't make sense
2737 QTest::newRow("ReadWrite") << int(QIODevice::ReadWrite);
2738 QTest::newRow("ReadOnly,Unbuffered") << int(QIODevice::ReadOnly | QIODevice::Unbuffered);
2739 QTest::newRow("ReadWrite,Unbuffered") << int(QIODevice::ReadWrite | QIODevice::Unbuffered);
2742 void tst_QFile::mapOpenMode()
2744 QFETCH(int, openMode);
2745 static const qint64 fileSize = 4096;
2746 QByteArray pattern(fileSize, 'A');
2748 QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
2749 if (QFile::exists(fileName)) {
2750 QVERIFY(QFile::setPermissions(fileName,
2751 QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
2752 QFile::remove(fileName);
2754 QFile file(fileName);
2756 // make a file
2757 QVERIFY(file.open(QFile::ReadWrite));
2758 QVERIFY(file.write(pattern));
2759 QVERIFY(file.flush());
2760 file.close();
2762 // open according to our mode
2763 QVERIFY(file.open(QIODevice::OpenMode(openMode)));
2765 uchar *memory = file.map(0, fileSize);
2766 QVERIFY(memory);
2767 QVERIFY(memcmp(memory, pattern, fileSize) == 0);
2769 if (openMode & QIODevice::WriteOnly) {
2770 // try to write to the file
2771 *memory = 'a';
2772 file.unmap(memory);
2773 file.close();
2774 file.open(QIODevice::OpenMode(openMode));
2775 file.seek(0);
2776 char c;
2777 QVERIFY(file.getChar(&c));
2778 QCOMPARE(c, 'a');
2781 file.close();
2784 void tst_QFile::openDirectory()
2786 QFile f1("resources");
2787 QVERIFY(!f1.open(QIODevice::ReadOnly));
2788 f1.close();
2789 QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered));
2792 void tst_QFile::openStandardStreams()
2794 // Using file descriptors
2796 QFile in;
2797 in.open(STDIN_FILENO, QIODevice::ReadOnly);
2798 QCOMPARE( in.pos(), (qint64)0 );
2799 QCOMPARE( in.size(), (qint64)0 );
2800 QVERIFY( in.isSequential() );
2804 QFile out;
2805 out.open(STDOUT_FILENO, QIODevice::WriteOnly);
2806 QCOMPARE( out.pos(), (qint64)0 );
2807 QCOMPARE( out.size(), (qint64)0 );
2808 QVERIFY( out.isSequential() );
2812 QFile err;
2813 err.open(STDERR_FILENO, QIODevice::WriteOnly);
2814 QCOMPARE( err.pos(), (qint64)0 );
2815 QCOMPARE( err.size(), (qint64)0 );
2816 QVERIFY( err.isSequential() );
2819 // Using streams
2821 QFile in;
2822 in.open(stdin, QIODevice::ReadOnly);
2823 QCOMPARE( in.pos(), (qint64)0 );
2824 QCOMPARE( in.size(), (qint64)0 );
2825 QVERIFY( in.isSequential() );
2829 QFile out;
2830 out.open(stdout, QIODevice::WriteOnly);
2831 QCOMPARE( out.pos(), (qint64)0 );
2832 QCOMPARE( out.size(), (qint64)0 );
2833 QVERIFY( out.isSequential() );
2837 QFile err;
2838 err.open(stderr, QIODevice::WriteOnly);
2839 QCOMPARE( err.pos(), (qint64)0 );
2840 QCOMPARE( err.size(), (qint64)0 );
2841 QVERIFY( err.isSequential() );
2845 void tst_QFile::writeNothing()
2847 for (int i = 0; i < 3; ++i) {
2848 QFile file("file.txt");
2849 QVERIFY( openFile(file, QIODevice::WriteOnly | QIODevice::Unbuffered, FileType(i)) );
2850 QVERIFY( 0 == file.write((char *)0, 0) );
2851 QCOMPARE( file.error(), QFile::NoError );
2852 closeFile(file);
2856 QTEST_MAIN(tst_QFile)
2857 #include "tst_qfile.moc"