Fix auto test
[qt-netbsd.git] / tests / auto / qfile / tst_qfile.cpp
blob9ee4d7c1bc945b74b9ec545d4e09544454a8cf64
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Qt Software Information (qt-info@nokia.com)
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** No Commercial Usage
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the either Technology Preview License Agreement or the
13 ** Beta Release License Agreement.
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at qt-sales@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 #ifndef Q_OS_WINCE
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>
77 #include "../network-settings.h"
79 Q_DECLARE_METATYPE(QFile::FileError)
81 //TESTED_CLASS=
82 //TESTED_FILES=
84 class tst_QFile : public QObject
86 Q_OBJECT
88 public:
89 tst_QFile();
90 virtual ~tst_QFile();
93 public slots:
94 void init();
95 void cleanup();
96 private slots:
97 void initTestCase();
98 void cleanupTestCase();
99 void exists();
100 void open_data();
101 void open();
102 void openUnbuffered();
103 void size_data();
104 void size();
105 void seek();
106 void setSize();
107 void setSizeSeek();
108 void atEnd();
109 void readLine();
110 void readLine2();
111 void readLineNullInLine();
112 void readAllStdin();
113 void readLineStdin();
114 void readLineStdin_lineByLine();
115 void text();
116 void missingEndOfLine();
117 void readBlock();
118 void getch();
119 void ungetChar();
120 void createFile();
121 void append();
122 void permissions_data();
123 void permissions();
124 void setPermissions();
125 void copy();
126 void copyRemovesTemporaryFile() const;
127 void copyShouldntOverwrite();
128 void copyFallback();
129 void link();
130 void linkToDir();
131 void absolutePathLinkToRelativePath();
132 void readBrokenLink();
133 void readTextFile_data();
134 void readTextFile();
135 void readTextFile2();
136 void writeTextFile_data();
137 void writeTextFile();
138 /* void largeFileSupport(); */
139 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
140 void largeUncFileSupport();
141 #endif
142 void tailFile();
143 void flush();
144 void bufferedRead();
145 void isSequential();
146 void encodeName();
147 void truncate();
148 void seekToPos();
149 void FILEReadWrite();
150 void i18nFileName_data();
151 void i18nFileName();
152 void longFileName_data();
153 void longFileName();
154 void fileEngineHandler();
155 void useQFileInAFileHandler();
156 void getCharFF();
157 void remove_and_exists();
158 void removeOpenFile();
159 void fullDisk();
160 void writeLargeDataBlock_data();
161 void writeLargeDataBlock();
162 void readFromWriteOnlyFile();
163 void writeToReadOnlyFile();
164 void virtualFile();
165 void textFile();
166 void rename_data();
167 void rename();
168 void renameWithAtEndSpecialFile() const;
169 void renameFallback();
170 void renameMultiple();
171 void appendAndRead();
172 void miscWithUncPathAsCurrentDir();
173 void standarderror();
174 void handle();
176 void readEof_data();
177 void readEof();
179 void map_data();
180 void map();
181 void mapResource_data();
182 void mapResource();
183 void mapOpenMode_data();
184 void mapOpenMode();
186 // --- Task related tests below this line
187 void task167217();
189 void openDirectory();
191 public:
192 // disabled this test for the moment... it hangs
193 void invalidFile_data();
194 void invalidFile();
197 tst_QFile::tst_QFile()
201 tst_QFile::~tst_QFile()
206 void tst_QFile::init()
208 // TODO: Add initialization code here.
209 // This will be executed immediately before each test is run.
212 void tst_QFile::cleanup()
214 // TODO: Add cleanup code here.
215 // This will be executed immediately after each test is run.
217 // for copyFallback()
218 if (QFile::exists("file-copy-destination.txt")) {
219 QFile::setPermissions("file-copy-destination.txt",
220 QFile::ReadOwner | QFile::WriteOwner);
221 QFile::remove("file-copy-destination.txt");
224 // for renameFallback()
225 QFile::remove("file-rename-destination.txt");
227 // for renameMultiple()
228 QFile::remove("file-to-be-renamed.txt");
229 QFile::remove("file-renamed-once.txt");
230 QFile::remove("file-renamed-twice.txt");
233 void tst_QFile::initTestCase()
235 QFile::remove("noreadfile");
237 // create a file and make it read-only
238 QFile file("readonlyfile");
239 file.open(QFile::WriteOnly);
240 file.write("a", 1);
241 file.close();
242 file.setPermissions(QFile::ReadOwner);
244 // create another file and make it not readable
245 file.setFileName("noreadfile");
246 file.open(QFile::WriteOnly);
247 file.write("b", 1);
248 file.close();
249 file.setPermissions(0);
252 void tst_QFile::cleanupTestCase()
254 // clean up the files we created
255 QFile::remove("readonlyfile");
256 QFile::remove("noreadfile");
257 QFile::remove("myLink.lnk");
258 QFile::remove("appendme.txt");
259 QFile::remove("createme.txt");
260 QFile::remove("file.txt");
261 QFile::remove("genfile.txt");
262 QFile::remove("seekToPos.txt");
263 QFile::remove("setsizeseek.txt");
264 QFile::remove("stdfile.txt");
265 QFile::remove("textfile.txt");
266 QFile::remove("truncate.txt");
267 QFile::remove("winfile.txt");
268 QFile::remove("writeonlyfile");
269 QFile::remove("largeblockfile.txt");
270 QFile::remove("tst_qfile_copy.cpp");
271 QFile::remove("nullinline.txt");
272 QFile::remove("myLink2.lnk");
273 QFile::remove("resources");
274 QFile::remove("qfile_map_testfile");
277 //------------------------------------------
278 // The 'testfile' is currently just a
279 // testfile. The path of this file, the
280 // attributes and the contents itself
281 // will be changed as far as we have a
282 // proper way to handle files in the
283 // testing enviroment.
284 //------------------------------------------
286 void tst_QFile::exists()
288 QFile f( SRCDIR "testfile.txt" );
289 QCOMPARE( f.exists(), (bool)TRUE );
291 QFile file("nobodyhassuchafile");
292 file.remove();
293 QVERIFY(!file.exists());
295 QFile file2("nobodyhassuchafile");
296 QVERIFY(file2.open(QIODevice::WriteOnly));
297 file2.close();
299 QVERIFY(file.exists());
301 QVERIFY(file.open(QIODevice::WriteOnly));
302 file.close();
303 QVERIFY(file.exists());
305 file.remove();
306 QVERIFY(!file.exists());
308 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
309 QFile unc("//" + QtNetworkSettings::winServerName() + "/testshare/readme.txt");
310 QVERIFY(unc.exists());
311 #endif
314 void tst_QFile::open_data()
316 QTest::addColumn<QString>("filename");
317 QTest::addColumn<int>("mode");
318 QTest::addColumn<bool>("ok");
319 QTest::addColumn<QFile::FileError>("status");
321 #ifdef Q_OS_MAC
322 static const QString denied("Operation not permitted");
323 #else
324 static const QString denied("Permission denied");
325 #endif
326 QTest::newRow( "exist_readOnly" )
327 << QString(SRCDIR "testfile.txt") << int(QIODevice::ReadOnly)
328 << (bool)TRUE << QFile::NoError;
330 QTest::newRow( "exist_writeOnly" )
331 << QString("readonlyfile")
332 << int(QIODevice::WriteOnly)
333 << (bool)FALSE
334 << QFile::OpenError;
336 QTest::newRow( "exist_append" )
337 << QString("readonlyfile") << int(QIODevice::Append)
338 << (bool)FALSE << QFile::OpenError;
340 QTest::newRow( "nonexist_readOnly" )
341 << QString("nonExist.txt") << int(QIODevice::ReadOnly)
342 << (bool)FALSE << QFile::OpenError;
344 QTest::newRow("emptyfile")
345 << QString("")
346 << int(QIODevice::ReadOnly)
347 << (bool)FALSE
348 << QFile::OpenError;
350 QTest::newRow("nullfile") << QString() << int(QIODevice::ReadOnly) << (bool)FALSE
351 << QFile::OpenError;
353 QTest::newRow("two-dots") << QString(SRCDIR "two.dots.file") << int(QIODevice::ReadOnly) << (bool)TRUE
354 << QFile::NoError;
356 QTest::newRow("readonlyfile") << QString("readonlyfile") << int(QIODevice::WriteOnly)
357 << (bool)FALSE << QFile::OpenError;
358 QTest::newRow("noreadfile") << QString("noreadfile") << int(QIODevice::ReadOnly)
359 << (bool)FALSE << QFile::OpenError;
360 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
361 QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly)
362 << (bool)TRUE << QFile::NoError;
363 QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testsharewritable/test.pri" << int(QIODevice::ReadOnly)
364 << true << QFile::NoError;
365 #endif
368 void tst_QFile::open()
370 QFETCH( QString, filename );
371 QFETCH( int, mode );
373 QFile f( filename );
375 QFETCH( bool, ok );
377 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
378 QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort);
379 #endif
380 if (filename.isEmpty())
381 QTest::ignoreMessage(QtWarningMsg, "QFSFileEngine::open: No file name specified");
383 QCOMPARE(f.open( QIODevice::OpenMode(mode) ), ok);
385 QTEST( f.error(), "status" );
388 void tst_QFile::openUnbuffered()
390 QFile file(SRCDIR "testfile.txt");
391 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
392 char c = '\0';
393 QVERIFY(file.seek(1));
394 QCOMPARE(file.pos(), qint64(1));
395 QVERIFY(file.getChar(&c));
396 QCOMPARE(file.pos(), qint64(2));
397 char d = '\0';
398 QVERIFY(file.seek(3));
399 QCOMPARE(file.pos(), qint64(3));
400 QVERIFY(file.getChar(&d));
401 QCOMPARE(file.pos(), qint64(4));
402 QVERIFY(file.seek(1));
403 QCOMPARE(file.pos(), qint64(1));
404 char c2 = '\0';
405 QVERIFY(file.getChar(&c2));
406 QCOMPARE(file.pos(), qint64(2));
407 QVERIFY(file.seek(3));
408 QCOMPARE(file.pos(), qint64(3));
409 char d2 = '\0';
410 QVERIFY(file.getChar(&d2));
411 QCOMPARE(file.pos(), qint64(4));
412 QCOMPARE(c, c2);
413 QCOMPARE(d, d2);
414 QCOMPARE(c, '-');
415 QCOMPARE(d, '-');
418 void tst_QFile::size_data()
420 QTest::addColumn<QString>("filename");
421 QTest::addColumn<int>("size");
423 QTest::newRow( "exist01" ) << QString(SRCDIR "testfile.txt") << 245;
424 QTest::newRow( "nonexist01" ) << QString("foo.txt") << 0;
425 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
426 // Only test UNC on Windows./
427 QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testsharewritable/test.pri") << 34;
428 #endif
431 void tst_QFile::size()
433 QFETCH( QString, filename );
434 QFile f( filename );
435 QTEST( (int)f.size(), "size" );
436 if (f.open(QFile::ReadOnly))
437 QTEST( (int)f.size(), "size" );
440 void tst_QFile::seek()
442 QFile::remove("newfile.txt");
443 QFile file("newfile.txt");
444 file.open(QIODevice::WriteOnly);
445 QCOMPARE(file.size(), qint64(0));
446 QCOMPARE(file.pos(), qint64(0));
447 QVERIFY(file.seek(10));
448 QCOMPARE(file.pos(), qint64(10));
449 QCOMPARE(file.size(), qint64(0));
450 QFile::remove("newfile.txt");
453 void tst_QFile::setSize()
455 DEPENDS_ON( "size" );
457 if ( QFile::exists( "createme.txt" ) )
458 QFile::remove( "createme.txt" );
459 QVERIFY( !QFile::exists( "createme.txt" ) );
461 QFile f("createme.txt");
462 QVERIFY(f.open(QIODevice::Truncate | QIODevice::ReadWrite));
463 f.putChar('a');
465 f.seek(0);
466 char c = '\0';
467 f.getChar(&c);
468 QCOMPARE(c, 'a');
470 QCOMPARE(f.size(), (qlonglong)1);
471 bool ok = f.resize(99);
472 QVERIFY(ok);
473 QCOMPARE(f.size(), (qlonglong)99);
475 f.seek(0);
476 c = '\0';
477 f.getChar(&c);
478 QCOMPARE(c, 'a');
480 QVERIFY(f.resize(1));
481 QCOMPARE(f.size(), (qlonglong)1);
483 f.seek(0);
484 c = '\0';
485 f.getChar(&c);
486 QCOMPARE(c, 'a');
488 f.close();
490 QCOMPARE(f.size(), (qlonglong)1);
491 QVERIFY(f.resize(100));
492 QCOMPARE(f.size(), (qlonglong)100);
493 QVERIFY(f.resize(50));
494 QCOMPARE(f.size(), (qlonglong)50);
497 void tst_QFile::setSizeSeek()
499 QFile::remove("setsizeseek.txt");
500 QFile f("setsizeseek.txt");
501 QVERIFY(f.open(QFile::WriteOnly));
502 f.write("ABCD");
504 QCOMPARE(f.pos(), qint64(4));
505 f.resize(2);
506 QCOMPARE(f.pos(), qint64(2));
507 f.resize(4);
508 QCOMPARE(f.pos(), qint64(2));
509 f.resize(0);
510 QCOMPARE(f.pos(), qint64(0));
511 f.resize(4);
512 QCOMPARE(f.pos(), qint64(0));
514 f.seek(3);
515 QCOMPARE(f.pos(), qint64(3));
516 f.resize(2);
517 QCOMPARE(f.pos(), qint64(2));
520 void tst_QFile::atEnd()
522 QFile f( SRCDIR "testfile.txt" );
523 QVERIFY(f.open( QIODevice::ReadOnly ));
525 int size = f.size();
526 f.seek( size );
528 bool end = f.atEnd();
529 f.close();
530 QCOMPARE( end, (bool)TRUE );
533 void tst_QFile::readLine()
535 QFile f( SRCDIR "testfile.txt" );
536 QVERIFY(f.open( QIODevice::ReadOnly ));
538 int i = 0;
539 char p[128];
540 int foo;
541 while ( (foo=f.readLine( p, 128 )) > 0 ) {
542 ++i;
543 if ( i == 5 ) {
544 QCOMPARE( p[0], 'T' );
545 QCOMPARE( p[3], 's' );
546 QCOMPARE( p[11], 'i' );
549 f.close();
550 QCOMPARE( i, 6 );
553 void tst_QFile::readLine2()
555 QFile f( SRCDIR "testfile.txt" );
556 f.open( QIODevice::ReadOnly );
558 char p[128];
559 QCOMPARE(f.readLine(p, 60), qlonglong(59));
560 QCOMPARE(f.readLine(p, 60), qlonglong(59));
561 memset(p, '@', sizeof(p));
562 QCOMPARE(f.readLine(p, 60), qlonglong(59));
564 QCOMPARE(p[57], '-');
565 QCOMPARE(p[58], '\n');
566 QCOMPARE(p[59], '\0');
567 QCOMPARE(p[60], '@');
570 void tst_QFile::readLineNullInLine()
572 QFile::remove("nullinline.txt");
573 QFile file("nullinline.txt");
574 QVERIFY(file.open(QIODevice::ReadWrite));
575 QVERIFY(file.write("linewith\0null\nanotherline\0withnull\n\0\nnull\0", 42) > 0);
576 QVERIFY(file.flush());
577 file.reset();
579 QCOMPARE(file.readLine(), QByteArray("linewith\0null\n", 14));
580 QCOMPARE(file.readLine(), QByteArray("anotherline\0withnull\n", 21));
581 QCOMPARE(file.readLine(), QByteArray("\0\n", 2));
582 QCOMPARE(file.readLine(), QByteArray("null\0", 5));
583 QCOMPARE(file.readLine(), QByteArray());
586 void tst_QFile::readAllStdin()
588 #if defined(Q_OS_WINCE)
589 QSKIP("Currently no stdin/out supported for Windows CE", SkipAll);
590 #endif
591 #if defined(QT_NO_PROCESS)
592 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
593 #else
594 QByteArray lotsOfData(1024, '@'); // 10 megs
596 QProcess process;
597 process.start("stdinprocess/stdinprocess all");
598 for (int i = 0; i < 5; ++i) {
599 QTest::qWait(1000);
600 process.write(lotsOfData);
601 while (process.bytesToWrite() > 0) {
602 QVERIFY(process.waitForBytesWritten());
606 process.closeWriteChannel();
607 process.waitForFinished();
608 QCOMPARE(process.readAll().size(), lotsOfData.size() * 5);
609 #endif
612 void tst_QFile::readLineStdin()
614 #if defined(Q_OS_WINCE)
615 QSKIP("Currently no stdin/out supported for Windows CE", SkipAll);
616 #endif
617 #if defined(QT_NO_PROCESS)
618 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
619 #else
621 QByteArray lotsOfData(1024, '@'); // 10 megs
622 for (int i = 0; i < lotsOfData.size(); ++i) {
623 if ((i % 32) == 31)
624 lotsOfData[i] = '\n';
625 else
626 lotsOfData[i] = char('0' + i % 32);
629 for (int i = 0; i < 2; ++i) {
630 QProcess process;
631 process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
632 for (int i = 0; i < 5; ++i) {
633 QTest::qWait(1000);
634 process.write(lotsOfData);
635 while (process.bytesToWrite() > 0) {
636 QVERIFY(process.waitForBytesWritten());
640 process.closeWriteChannel();
641 QVERIFY(process.waitForFinished(5000));
643 QByteArray array = process.readAll();
644 QCOMPARE(array.size(), lotsOfData.size() * 5);
645 for (int i = 0; i < array.size(); ++i) {
646 if ((i % 32) == 31)
647 QCOMPARE(char(array[i]), '\n');
648 else
649 QCOMPARE(char(array[i]), char('0' + i % 32));
652 #endif
655 void tst_QFile::readLineStdin_lineByLine()
657 #if defined(Q_OS_WINCE)
658 QSKIP("Currently no stdin/out supported for Windows CE", SkipAll);
659 #endif
660 #if defined(QT_NO_PROCESS)
661 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll);
662 #else
663 for (int i = 0; i < 2; ++i) {
664 QProcess process;
665 process.start(QString("stdinprocess/stdinprocess line %1").arg(i), QIODevice::Text | QIODevice::ReadWrite);
666 QVERIFY(process.waitForStarted());
668 for (int j = 0; j < 3; ++j) {
669 QByteArray line = "line " + QByteArray::number(j) + "\n";
670 QCOMPARE(process.write(line), qint64(line.size()));
671 QVERIFY(process.waitForBytesWritten(2000));
672 if (process.bytesAvailable() == 0)
673 QVERIFY(process.waitForReadyRead(2000));
674 QCOMPARE(process.readAll(), line);
677 process.closeWriteChannel();
678 QVERIFY(process.waitForFinished(5000));
680 #endif
683 void tst_QFile::text()
685 // dosfile.txt is a binary CRLF file
686 QFile file(SRCDIR "dosfile.txt");
687 QVERIFY(file.open(QFile::Text | QFile::ReadOnly));
688 QCOMPARE(file.readLine(),
689 QByteArray("/dev/system/root / reiserfs acl,user_xattr 1 1\n"));
690 QCOMPARE(file.readLine(),
691 QByteArray("/dev/sda1 /boot ext3 acl,user_xattr 1 2\n"));
692 file.ungetChar('\n');
693 file.ungetChar('2');
694 QCOMPARE(file.readLine().constData(), QByteArray("2\n").constData());
697 void tst_QFile::missingEndOfLine()
699 QFile file(SRCDIR "noendofline.txt");
700 QVERIFY(file.open(QFile::ReadOnly));
702 int nlines = 0;
703 while (!file.atEnd()) {
704 ++nlines;
705 file.readLine();
708 QCOMPARE(nlines, 3);
711 void tst_QFile::readBlock()
713 QFile f( SRCDIR "testfile.txt" );
714 f.open( QIODevice::ReadOnly );
716 int length = 0;
717 char p[256];
718 length = f.read( p, 256 );
719 f.close();
720 QCOMPARE( length, 245 );
721 QCOMPARE( p[59], 'D' );
722 QCOMPARE( p[178], 'T' );
723 QCOMPARE( p[199], 'l' );
726 void tst_QFile::getch()
728 QFile f( SRCDIR "testfile.txt" );
729 f.open( QIODevice::ReadOnly );
731 char c;
732 int i = 0;
733 while (f.getChar(&c)) {
734 QCOMPARE(f.pos(), qint64(i + 1));
735 if ( i == 59 )
736 QCOMPARE( c, 'D' );
737 ++i;
739 f.close();
740 QCOMPARE( i, 245 );
743 void tst_QFile::ungetChar()
745 QFile f(SRCDIR "testfile.txt");
746 QVERIFY(f.open(QIODevice::ReadOnly));
748 QByteArray array = f.readLine();
749 QCOMPARE(array.constData(), "----------------------------------------------------------\n");
750 f.ungetChar('\n');
752 array = f.readLine();
753 QCOMPARE(array.constData(), "\n");
755 f.ungetChar('\n');
756 f.ungetChar('-');
757 f.ungetChar('-');
759 array = f.readLine();
760 QCOMPARE(array.constData(), "--\n");
762 QFile::remove("genfile.txt");
763 QFile out("genfile.txt");
764 QVERIFY(out.open(QIODevice::ReadWrite));
765 out.write("123");
766 out.seek(0);
767 QCOMPARE(out.readAll().constData(), "123");
768 out.ungetChar('3');
769 out.write("4");
770 out.seek(0);
771 QCOMPARE(out.readAll().constData(), "124");
772 out.ungetChar('4');
773 out.ungetChar('2');
774 out.ungetChar('1');
775 char buf[3];
776 QCOMPARE(out.read(buf, sizeof(buf)), qint64(3));
777 QCOMPARE(buf[0], '1');
778 QCOMPARE(buf[1], '2');
779 QCOMPARE(buf[2], '4');
782 void tst_QFile::invalidFile_data()
784 QTest::addColumn<QString>("fileName");
785 #ifndef Q_WS_WIN
786 QTest::newRow( "x11" ) << QString( "qwe//" );
787 #else
788 QTest::newRow( "colon1" ) << QString( "fail:invalid" );
789 QTest::newRow( "colon2" ) << QString( "f:ail:invalid" );
790 QTest::newRow( "colon3" ) << QString( ":failinvalid" );
791 QTest::newRow( "forwardslash" ) << QString( "fail/invalid" );
792 QTest::newRow( "asterisk" ) << QString( "fail*invalid" );
793 QTest::newRow( "questionmark" ) << QString( "fail?invalid" );
794 QTest::newRow( "quote" ) << QString( "fail\"invalid" );
795 QTest::newRow( "lt" ) << QString( "fail<invalid" );
796 QTest::newRow( "gt" ) << QString( "fail>invalid" );
797 QTest::newRow( "pipe" ) << QString( "fail|invalid" );
798 #endif
801 void tst_QFile::invalidFile()
803 QFETCH( QString, fileName );
804 QFile f( fileName );
805 QVERIFY( !f.open( QIODevice::ReadWrite ) );
808 void tst_QFile::createFile()
810 if ( QFile::exists( "createme.txt" ) )
811 QFile::remove( "createme.txt" );
812 QVERIFY( !QFile::exists( "createme.txt" ) );
814 QFile f( "createme.txt" );
815 QVERIFY( f.open( QIODevice::WriteOnly ) );
816 f.close();
817 QVERIFY( QFile::exists( "createme.txt" ) );
820 void tst_QFile::append()
822 const QString name("appendme.txt");
823 if (QFile::exists(name))
824 QFile::remove(name);
825 QVERIFY(!QFile::exists(name));
827 QFile f(name);
828 QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
829 f.putChar('a');
830 f.close();
832 QVERIFY(f.open(QIODevice::Append));
833 QVERIFY(f.pos() == 1);
834 f.putChar('a');
835 f.close();
836 QCOMPARE(int(f.size()), 2);
839 void tst_QFile::permissions_data()
841 QTest::addColumn<QString>("file");
842 QTest::addColumn<uint>("perms");
843 QTest::addColumn<bool>("expected");
845 QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser) << true;
846 QTest::newRow("data1") << SRCDIR "tst_qfile.cpp" << uint(QFile::ReadUser) << true;
847 // QTest::newRow("data2") << "tst_qfile.cpp" << int(QFile::WriteUser) << false;
848 QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ReadUser) << true;
849 QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::WriteUser) << false;
850 QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ExeUser) << false;
853 void tst_QFile::permissions()
855 QFETCH(QString, file);
856 QFETCH(uint, perms);
857 QFETCH(bool, expected);
858 QFile f(file);
859 QCOMPARE(((f.permissions() & perms) == QFile::Permissions(perms)), expected);
862 void tst_QFile::setPermissions()
864 DEPENDS_ON( "permissions" ); //if that doesn't work...
866 if ( QFile::exists( "createme.txt" ) )
867 QFile::remove( "createme.txt" );
868 QVERIFY( !QFile::exists( "createme.txt" ) );
870 QFile f("createme.txt");
871 QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate));
872 f.putChar('a');
873 f.close();
875 QFile::Permissions perms(QFile::WriteUser | QFile::ReadUser);
876 QVERIFY(f.setPermissions(perms));
877 QVERIFY((f.permissions() & perms) == perms);
881 void tst_QFile::copy()
883 QFile::setPermissions("tst_qfile_copy.cpp", QFile::WriteUser);
884 QFile::remove("tst_qfile_copy.cpp");
885 QFile::remove("test2");
886 QVERIFY(QFile::copy(SRCDIR "tst_qfile.cpp", "tst_qfile_copy.cpp"));
887 QFile in1(SRCDIR "tst_qfile.cpp"), in2("tst_qfile_copy.cpp");
888 QVERIFY(in1.open(QFile::ReadOnly));
889 QVERIFY(in2.open(QFile::ReadOnly));
890 QByteArray data1 = in1.readAll(), data2 = in2.readAll();
891 QCOMPARE(data1, data2);
892 QFile::remove( "main_copy.cpp" );
894 QFile::copy(QDir::currentPath(), QDir::currentPath() + QLatin1String("/test2"));
897 void tst_QFile::copyRemovesTemporaryFile() const
899 const QString newName(QLatin1String("copyRemovesTemporaryFile"));
900 QVERIFY(QFile::copy(SRCDIR "forCopying.txt", newName));
902 QVERIFY(!QFile::exists(QLatin1String( SRCDIR "qt_temp.XXXXXX")));
903 QVERIFY(QFile::remove(newName));
906 void tst_QFile::copyShouldntOverwrite()
908 // Copy should not overwrite existing files.
909 QFile::remove("tst_qfile.cpy");
910 QFile file(SRCDIR "tst_qfile.cpp");
911 QVERIFY(file.copy("tst_qfile.cpy"));
912 bool ok = QFile::setPermissions("tst_qfile.cpy", QFile::WriteOther);
913 QVERIFY(ok);
914 QVERIFY(!file.copy("tst_qfile.cpy"));
915 QFile::remove("tst_qfile.cpy");
918 void tst_QFile::copyFallback()
920 // Using a resource file to trigger QFile::copy's fallback handling
921 QFile file(":/copy-fallback.qrc");
922 QFile::remove("file-copy-destination.txt");
924 QVERIFY2(file.exists(), "test precondition");
925 QVERIFY2(!QFile::exists("file-copy-destination.txt"), "test precondition");
927 // Fallback copy of closed file.
928 QVERIFY(file.copy("file-copy-destination.txt"));
929 QVERIFY(QFile::exists("file-copy-destination.txt"));
930 QVERIFY(!file.isOpen());
932 // Need to reset permissions on Windows to be able to delete
933 QVERIFY(QFile::setPermissions("file-copy-destination.txt",
934 QFile::ReadOwner | QFile::WriteOwner));
935 QVERIFY(QFile::remove("file-copy-destination.txt"));
937 // Fallback copy of open file.
938 QVERIFY(file.open(QIODevice::ReadOnly));
939 QVERIFY(file.copy("file-copy-destination.txt"));
940 QVERIFY(QFile::exists("file-copy-destination.txt"));
941 QVERIFY(!file.isOpen());
943 QFile::remove("file-copy-destination.txt");
946 #ifdef Q_OS_WIN
947 #include <objbase.h>
948 #include <shlobj.h>
949 #endif
951 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
952 static QString getWorkingDirectoryForLink(const QString &linkFileName)
954 bool neededCoInit = false;
955 QString ret;
956 QT_WA({
957 IShellLink *psl;
958 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
959 if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
960 neededCoInit = true;
961 CoInitialize(NULL);
962 hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
965 if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
966 IPersistFile *ppf;
967 hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
968 if (SUCCEEDED(hres)) {
969 hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
970 //The original path of the link is retrieved. If the file/folder
971 //was moved, the return value still have the old path.
972 if(SUCCEEDED(hres)) {
973 wchar_t szGotPath[MAX_PATH];
974 if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
975 ret = QString::fromUtf16((ushort*)szGotPath);
977 ppf->Release();
979 psl->Release();
982 IShellLinkA *psl;
983 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
984 if (hres == CO_E_NOTINITIALIZED) { // COM was not initialized
985 neededCoInit = true;
986 CoInitialize(NULL);
987 hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl);
990 if (SUCCEEDED(hres)) { // Get pointer to the IPersistFile interface.
991 IPersistFile *ppf;
992 hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf);
993 if (SUCCEEDED(hres)) {
994 hres = ppf->Load((LPOLESTR)linkFileName.utf16(), STGM_READ);
995 //The original path of the link is retrieved. If the file/folder
996 //was moved, the return value still have the old path.
997 if(SUCCEEDED(hres)) {
998 char szGotPath[MAX_PATH];
999 if (psl->GetWorkingDirectory(szGotPath, MAX_PATH) == NOERROR)
1000 ret = QString::fromLocal8Bit(szGotPath);
1002 ppf->Release();
1004 psl->Release();
1007 if (neededCoInit) {
1008 CoUninitialize();
1011 return ret;
1013 #endif
1015 void tst_QFile::link()
1017 QFile::remove("myLink.lnk");
1018 QFileInfo info1("tst_qfile.cpp");
1019 QVERIFY(QFile::link("tst_qfile.cpp", "myLink.lnk"));
1020 QFileInfo info2("myLink.lnk");
1021 QVERIFY(info2.isSymLink());
1022 #ifdef Q_OS_WIN // on windows links are always absolute
1023 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1024 #else
1025 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1026 #endif
1028 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1029 QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath());
1030 QCOMPARE(QDir::fromNativeSeparators(wd), info1.absolutePath());
1031 #endif
1032 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1035 void tst_QFile::linkToDir()
1037 QFile::remove("myLinkToDir.lnk");
1038 QDir dir;
1039 dir.mkdir("myDir");
1040 QFileInfo info1("myDir");
1041 QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
1042 QFileInfo info2("myLinkToDir.lnk");
1043 #if !(defined Q_OS_HPUX && defined(__ia64))
1044 // absurd HP-UX filesystem bug on gravlaks - checking if a symlink
1045 // resolves or not alters the file system to make the broken symlink
1046 // later fail...
1047 QVERIFY(info2.isSymLink());
1048 #endif
1049 #ifdef Q_OS_WIN // on windows links are alway absolute
1050 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1051 #else
1052 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1053 #endif
1054 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1055 QFile::remove("myLinkToDir.lnk");
1056 dir.rmdir("myDir");
1059 void tst_QFile::absolutePathLinkToRelativePath()
1061 QFile::remove("myDir/test.txt");
1062 QFile::remove("myDir/myLink.lnk");
1063 QDir dir;
1064 dir.mkdir("myDir");
1065 QFile("myDir/test.txt").open(QFile::WriteOnly);
1067 #ifdef Q_OS_WIN
1068 QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk"));
1069 #else
1070 QVERIFY(QFile::link("myDir/test.txt", "myDir/myLink.lnk"));
1071 #endif
1073 QEXPECT_FAIL("", "Symlinking using relative paths is currently different on Windows and Unix", Continue);
1074 QCOMPARE(QFileInfo(QFile(QFileInfo("myDir/myLink.lnk").absoluteFilePath()).symLinkTarget()).absoluteFilePath(),
1075 QFileInfo("myDir/test.txt").absoluteFilePath());
1077 QFile::remove("myDir/test.txt");
1078 QFile::remove("myDir/myLink.lnk");
1079 dir.rmdir("myDir");
1082 void tst_QFile::readBrokenLink()
1084 QFile::remove("myLink2.lnk");
1085 QFileInfo info1("file12");
1086 QVERIFY(QFile::link("file12", "myLink2.lnk"));
1087 QFileInfo info2("myLink2.lnk");
1088 QVERIFY(info2.isSymLink());
1089 #ifdef Q_OS_WIN // on windows links are alway absolute
1090 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1091 #else
1092 QCOMPARE(info2.symLinkTarget(), info1.absoluteFilePath());
1093 #endif
1094 QVERIFY(QFile::remove(info2.absoluteFilePath()));
1096 QVERIFY(QFile::link("ole/..", "myLink2.lnk"));
1097 QCOMPARE(QFileInfo("myLink2.lnk").symLinkTarget(), QDir::currentPath());
1100 void tst_QFile::readTextFile_data()
1102 QTest::addColumn<QByteArray>("in");
1103 QTest::addColumn<QByteArray>("out");
1105 QTest::newRow("empty") << QByteArray() << QByteArray();
1106 QTest::newRow("a") << QByteArray("a") << QByteArray("a");
1107 QTest::newRow("a\\rb") << QByteArray("a\rb") << QByteArray("ab");
1108 QTest::newRow("\\n") << QByteArray("\n") << QByteArray("\n");
1109 QTest::newRow("\\r\\n") << QByteArray("\r\n") << QByteArray("\n");
1110 QTest::newRow("\\r") << QByteArray("\r") << QByteArray();
1111 QTest::newRow("twolines") << QByteArray("Hello\r\nWorld\r\n") << QByteArray("Hello\nWorld\n");
1112 QTest::newRow("twolines no endline") << QByteArray("Hello\r\nWorld") << QByteArray("Hello\nWorld");
1115 void tst_QFile::readTextFile()
1117 QFETCH(QByteArray, in);
1118 QFETCH(QByteArray, out);
1120 QFile winfile("winfile.txt");
1121 QVERIFY(winfile.open(QFile::WriteOnly | QFile::Truncate));
1122 winfile.write(in);
1123 winfile.close();
1125 QVERIFY(winfile.open(QFile::ReadOnly));
1126 QCOMPARE(winfile.readAll(), in);
1127 winfile.close();
1129 QVERIFY(winfile.open(QFile::ReadOnly | QFile::Text));
1130 QCOMPARE(winfile.readAll(), out);
1133 void tst_QFile::readTextFile2()
1136 QFile file(SRCDIR "testlog.txt");
1137 QVERIFY(file.open(QIODevice::ReadOnly));
1138 file.read(4097);
1142 QFile file(SRCDIR "testlog.txt");
1143 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text));
1144 file.read(4097);
1148 void tst_QFile::writeTextFile_data()
1150 QTest::addColumn<QByteArray>("in");
1152 QTest::newRow("empty") << QByteArray();
1153 QTest::newRow("a") << QByteArray("a");
1154 QTest::newRow("a\\rb") << QByteArray("a\rb");
1155 QTest::newRow("\\n") << QByteArray("\n");
1156 QTest::newRow("\\r\\n") << QByteArray("\r\n");
1157 QTest::newRow("\\r") << QByteArray("\r");
1158 QTest::newRow("twolines crlf") << QByteArray("Hello\r\nWorld\r\n");
1159 QTest::newRow("twolines crlf no endline") << QByteArray("Hello\r\nWorld");
1160 QTest::newRow("twolines lf") << QByteArray("Hello\nWorld\n");
1161 QTest::newRow("twolines lf no endline") << QByteArray("Hello\nWorld");
1162 QTest::newRow("mixed") << QByteArray("this\nis\r\na\nmixed\r\nfile\n");
1165 void tst_QFile::writeTextFile()
1167 QFETCH(QByteArray, in);
1169 QFile file("textfile.txt");
1170 QVERIFY(file.open(QFile::WriteOnly | QFile::Truncate | QFile::Text));
1171 QByteArray out = in;
1172 #ifdef Q_OS_WIN
1173 out.replace('\n', "\r\n");
1174 #endif
1175 QCOMPARE(file.write(in), qlonglong(in.size()));
1176 file.close();
1178 file.open(QFile::ReadOnly);
1179 QCOMPARE(file.readAll(), out);
1182 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1183 void tst_QFile::largeUncFileSupport()
1185 qint64 size = Q_INT64_C(8589934592);
1186 qint64 dataOffset = Q_INT64_C(8589914592);
1187 QByteArray knownData("LargeFile content at offset 8589914592");
1188 QString largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin");
1191 // 1) Native file handling.
1192 QFile file(largeFile);
1193 QCOMPARE(file.size(), size);
1194 QVERIFY(file.open(QIODevice::ReadOnly));
1195 QCOMPARE(file.size(), size);
1196 QVERIFY(file.seek(dataOffset));
1197 QCOMPARE(file.read(knownData.size()), knownData);
1200 // 2) stdlib file handling.
1201 #if _MSC_VER <= 1310
1202 QSKIP("platform SDK for MSVC 2003 does not support large files", SkipAll);
1203 #endif
1204 QFile file;
1205 FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
1206 QVERIFY(file.open(fh, QIODevice::ReadOnly));
1207 QCOMPARE(file.size(), size);
1208 QVERIFY(file.seek(dataOffset));
1209 QCOMPARE(file.read(knownData.size()), knownData);
1210 fclose(fh);
1213 // 3) stdio file handling.
1214 QFile file;
1215 FILE *fh = fopen(QFile::encodeName(largeFile).data(), "rb");
1216 int fd = int(_fileno(fh));
1217 QVERIFY(file.open(fd, QIODevice::ReadOnly));
1218 QCOMPARE(file.size(), size);
1219 QVERIFY(file.seek(dataOffset));
1220 QCOMPARE(file.read(knownData.size()), knownData);
1221 fclose(fh);
1224 #endif
1226 void tst_QFile::tailFile()
1228 QSKIP("File change notifications are so far unsupported.", SkipAll);
1230 QFile file("tail.txt");
1231 QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
1233 QFile tailFile("tail.txt");
1234 QVERIFY(tailFile.open(QFile::ReadOnly));
1235 tailFile.seek(file.size());
1237 QSignalSpy readSignal(&tailFile, SIGNAL(readyRead()));
1239 file.write("", 1);
1241 QTestEventLoop::instance().enterLoop(5);
1243 QVERIFY(!QTestEventLoop::instance().timeout());
1244 QCOMPARE(readSignal.count(), 1);
1247 void tst_QFile::flush()
1249 QString fileName("stdfile.txt");
1251 QFile::remove(fileName);
1254 QFile file(fileName);
1255 QVERIFY(file.open(QFile::WriteOnly));
1256 QCOMPARE(file.write("abc", 3),qint64(3));
1260 QFile file(fileName);
1261 QVERIFY(file.open(QFile::WriteOnly | QFile::Append));
1262 QCOMPARE(file.pos(), qlonglong(3));
1263 QCOMPARE(file.write("def", 3), qlonglong(3));
1264 QCOMPARE(file.pos(), qlonglong(6));
1268 QFile file("stdfile.txt");
1269 QVERIFY(file.open(QFile::ReadOnly));
1270 QCOMPARE(file.readAll(), QByteArray("abcdef"));
1273 QFile::remove(fileName);
1276 void tst_QFile::bufferedRead()
1278 QFile::remove("stdfile.txt");
1280 QFile file("stdfile.txt");
1281 QVERIFY(file.open(QFile::WriteOnly));
1282 file.write("abcdef");
1283 file.close();
1285 #if defined(Q_OS_WINCE)
1286 FILE *stdFile = fopen((QCoreApplication::applicationDirPath() + "/stdfile.txt").toAscii() , "r");
1287 #else
1288 FILE *stdFile = fopen("stdfile.txt", "r");
1289 #endif
1290 QVERIFY(stdFile);
1291 char c;
1292 QCOMPARE(int(fread(&c, 1, 1, stdFile)), 1);
1293 QCOMPARE(c, 'a');
1294 QCOMPARE(int(ftell(stdFile)), 1);
1297 QFile file;
1298 QVERIFY(file.open(stdFile, QFile::ReadOnly));
1299 QCOMPARE(file.pos(), qlonglong(1));
1300 QCOMPARE(file.read(&c, 1), qlonglong(1));
1301 QCOMPARE(c, 'b');
1302 QCOMPARE(file.pos(), qlonglong(2));
1305 fclose(stdFile);
1308 void tst_QFile::isSequential()
1310 #if defined (Q_OS_WIN)
1311 QSKIP("Unix only test.", SkipAll);
1312 #endif
1314 QFile zero("/dev/null");
1315 QVERIFY(zero.open(QFile::ReadOnly));
1316 QVERIFY(zero.isSequential());
1319 void tst_QFile::encodeName()
1321 QCOMPARE(QFile::encodeName(QString::null), QByteArray());
1324 void tst_QFile::truncate()
1326 for (int i = 0; i < 2; ++i) {
1327 QFile file("truncate.txt");
1328 QVERIFY(file.open(QFile::WriteOnly));
1329 file.write(QByteArray(200, '@'));
1330 file.close();
1332 QVERIFY(file.open((i ? QFile::WriteOnly : QFile::ReadWrite) | QFile::Truncate));
1333 file.write(QByteArray(100, '$'));
1334 file.close();
1336 QVERIFY(file.open(QFile::ReadOnly));
1337 QCOMPARE(file.readAll(), QByteArray(100, '$'));
1341 void tst_QFile::seekToPos()
1344 QFile file("seekToPos.txt");
1345 QVERIFY(file.open(QFile::WriteOnly));
1346 file.write("a\r\nb\r\nc\r\n");
1347 file.flush();
1350 QFile file("seekToPos.txt");
1351 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1352 file.seek(1);
1353 char c;
1354 QVERIFY(file.getChar(&c));
1355 QCOMPARE(c, '\n');
1357 QCOMPARE(file.pos(), qint64(3));
1358 file.seek(file.pos());
1359 QCOMPARE(file.pos(), qint64(3));
1361 file.seek(1);
1362 file.seek(file.pos());
1363 QCOMPARE(file.pos(), qint64(1));
1368 void tst_QFile::FILEReadWrite()
1370 // Tests modifing a file. First creates it then reads in 4 bytes and then overwrites these
1371 // 4 bytes with new values. At the end check to see the file contains the new values.
1373 QFile::remove("FILEReadWrite.txt");
1375 // create test file
1377 QFile f("FILEReadWrite.txt");
1378 QVERIFY(f.open(QFile::WriteOnly));
1379 QDataStream ds(&f);
1380 qint8 c = 0;
1381 ds << c;
1382 c = 1;
1383 ds << c;
1384 c = 2;
1385 ds << c;
1386 c = 3;
1387 ds << c;
1388 c = 4;
1389 ds << c;
1390 c = 5;
1391 ds << c;
1392 c = 6;
1393 ds << c;
1394 c = 7;
1395 ds << c;
1396 c = 8;
1397 ds << c;
1398 c = 9;
1399 ds << c;
1400 c = 10;
1401 ds << c;
1402 c = 11;
1403 ds << c;
1404 f.close();
1407 #ifdef Q_OS_WINCE
1408 FILE *fp = fopen(qPrintable(QCoreApplication::applicationDirPath() + "\\FILEReadWrite.txt"), "r+b");
1409 #else
1410 FILE *fp = fopen("FILEReadWrite.txt", "r+b");
1411 #endif
1412 QVERIFY(fp);
1413 QFile file;
1414 QVERIFY(file.open(fp, QFile::ReadWrite));
1415 QDataStream sfile(&file) ;
1417 qint8 var1,var2,var3,var4;
1418 while (!sfile.atEnd())
1420 qint64 base = file.pos();
1422 QCOMPARE(file.pos(), base + 0);
1423 sfile >> var1;
1424 QCOMPARE(file.pos(), base + 1);
1425 file.flush(); // flushing should not change the base
1426 QCOMPARE(file.pos(), base + 1);
1427 sfile >> var2;
1428 QCOMPARE(file.pos(), base + 2);
1429 sfile >> var3;
1430 QCOMPARE(file.pos(), base + 3);
1431 sfile >> var4;
1432 QCOMPARE(file.pos(), base + 4);
1433 file.seek(file.pos() - 4) ; // Move it back 4, for we are going to write new values based on old ones
1434 QCOMPARE(file.pos(), base + 0);
1435 sfile << qint8(var1 + 5);
1436 QCOMPARE(file.pos(), base + 1);
1437 sfile << qint8(var2 + 5);
1438 QCOMPARE(file.pos(), base + 2);
1439 sfile << qint8(var3 + 5);
1440 QCOMPARE(file.pos(), base + 3);
1441 sfile << qint8(var4 + 5);
1442 QCOMPARE(file.pos(), base + 4);
1445 file.close();
1446 fclose(fp);
1448 // check modified file
1450 QFile f("FILEReadWrite.txt");
1451 QVERIFY(f.open(QFile::ReadOnly));
1452 QDataStream ds(&f);
1453 qint8 c = 0;
1454 ds >> c;
1455 QCOMPARE(c, (qint8)5);
1456 ds >> c;
1457 QCOMPARE(c, (qint8)6);
1458 ds >> c;
1459 QCOMPARE(c, (qint8)7);
1460 ds >> c;
1461 QCOMPARE(c, (qint8)8);
1462 ds >> c;
1463 QCOMPARE(c, (qint8)9);
1464 ds >> c;
1465 QCOMPARE(c, (qint8)10);
1466 ds >> c;
1467 QCOMPARE(c, (qint8)11);
1468 ds >> c;
1469 QCOMPARE(c, (qint8)12);
1470 ds >> c;
1471 QCOMPARE(c, (qint8)13);
1472 ds >> c;
1473 QCOMPARE(c, (qint8)14);
1474 ds >> c;
1475 QCOMPARE(c, (qint8)15);
1476 ds >> c;
1477 QCOMPARE(c, (qint8)16);
1478 f.close();
1481 QFile::remove("FILEReadWrite.txt");
1486 #include <qglobal.h>
1487 #define BUFFSIZE 1
1488 #define FILESIZE 0x10000000f
1489 void tst_QFile::largeFileSupport()
1491 #ifdef Q_OS_SOLARIS
1492 QSKIP("Solaris does not support statfs", SkipAll);
1493 #else
1494 qlonglong sizeNeeded = 2147483647;
1495 sizeNeeded *= 2;
1496 sizeNeeded += 1024;
1497 qlonglong freespace = qlonglong(0);
1498 #ifdef Q_WS_WIN
1499 _ULARGE_INTEGER free;
1500 if (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) {
1501 if (::GetDiskFreeSpaceExW((wchar_t *)QDir::currentPath().utf16(), &free, 0, 0))
1502 freespace = free.QuadPart;
1503 } else {
1504 if (::GetDiskFreeSpaceExA(QDir::currentPath().local8Bit(), &free, 0, 0))
1505 freespace = free.QuadPart;
1507 if (freespace != 0) {
1508 #elif defined(Q_OS_IRIX)
1509 struct statfs info;
1510 if (statfs(QDir::currentPath().local8Bit(), &info, sizeof(struct statfs), 0) == 0) {
1511 freespace = qlonglong(info.f_bfree * info.f_bsize);
1512 #else
1513 struct statfs info;
1514 if (statfs(const_cast<char *>(QDir::currentPath().toLocal8Bit().constData()), &info) == 0) {
1515 freespace = qlonglong(info.f_bavail * info.f_bsize);
1516 #endif
1517 if (freespace > sizeNeeded) {
1518 QFile bigFile("bigfile");
1519 if (bigFile.open(QFile::ReadWrite)) {
1520 char c[BUFFSIZE] = {'a'};
1521 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
1522 qlonglong oldPos = bigFile.pos();
1523 QVERIFY(bigFile.resize(sizeNeeded));
1524 QCOMPARE(oldPos, bigFile.pos());
1525 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
1526 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
1528 bigFile.close();
1529 if (bigFile.open(QFile::ReadOnly)) {
1530 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
1531 int i = 0;
1532 for (i=0; i<BUFFSIZE; i++)
1533 QCOMPARE(c[i], 'a');
1534 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
1535 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
1536 for (i=0; i<BUFFSIZE; i++)
1537 QCOMPARE(c[i], 'a');
1538 bigFile.close();
1539 QVERIFY(bigFile.remove());
1540 } else {
1541 QVERIFY(bigFile.remove());
1542 QFAIL("Could not reopen file");
1544 } else {
1545 QFAIL("Could not open file");
1547 } else {
1548 QSKIP("Not enough space to run test", SkipSingle);
1550 } else {
1551 QFAIL("Could not determin disk space");
1553 #endif
1557 void tst_QFile::i18nFileName_data()
1559 QTest::addColumn<QString>("fileName");
1561 QTest::newRow( "01" ) << QString::fromUtf8("xxxxxxx.txt");
1564 void tst_QFile::i18nFileName()
1566 QFETCH(QString, fileName);
1567 if (QFile::exists(fileName)) {
1568 QVERIFY(QFile::remove(fileName));
1571 QFile file(fileName);
1572 QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
1573 QTextStream ts(&file);
1574 ts.setCodec("UTF-8");
1575 ts << fileName << endl;
1578 QFile file(fileName);
1579 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1580 QTextStream ts(&file);
1581 ts.setCodec("UTF-8");
1582 QString line = ts.readLine();
1583 QCOMPARE(line, fileName);
1585 QVERIFY(QFile::remove(fileName));
1589 void tst_QFile::longFileName_data()
1591 QTest::addColumn<QString>("fileName");
1593 QTest::newRow( "16 chars" ) << QString::fromLatin1("longFileName.txt");
1594 QTest::newRow( "52 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName.txt");
1595 QTest::newRow( "148 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1596 "longFileNamelongFileNamelongFileNamelongFileName"
1597 "longFileNamelongFileNamelongFileNamelongFileName.txt");
1598 QTest::newRow( "244 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1599 "longFileNamelongFileNamelongFileNamelongFileName"
1600 "longFileNamelongFileNamelongFileNamelongFileName"
1601 "longFileNamelongFileNamelongFileNamelongFileName"
1602 "longFileNamelongFileNamelongFileNamelongFileName.txt");
1603 QTest::newRow( "244 chars to absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1604 "longFileNamelongFileNamelongFileNamelongFileName"
1605 "longFileNamelongFileNamelongFileNamelongFileName"
1606 "longFileNamelongFileNamelongFileNamelongFileName"
1607 "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath();
1608 /* needs to be put on a windows 2000 > test machine
1609 QTest::newRow( "244 chars on UNC" ) << QString::fromLatin1("//arsia/D/troll/tmp/longFileNamelongFileNamelongFileNamelongFileName"
1610 "longFileNamelongFileNamelongFileNamelongFileName"
1611 "longFileNamelongFileNamelongFileNamelongFileName"
1612 "longFileNamelongFileNamelongFileNamelongFileName"
1613 "longFileNamelongFileNamelongFileNamelongFileName.txt");*/
1616 void tst_QFile::longFileName()
1618 QFETCH(QString, fileName);
1619 if (QFile::exists(fileName)) {
1620 QVERIFY(QFile::remove(fileName));
1623 QFile file(fileName);
1624 #if defined(Q_WS_WIN)
1625 #if !defined(Q_OS_WINCE)
1626 QT_WA({ if (false) ; }, {
1627 QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
1628 QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
1630 #else
1631 QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort);
1632 QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort);
1633 #endif
1634 #endif
1635 QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
1636 QTextStream ts(&file);
1637 ts << fileName << endl;
1640 QFile file(fileName);
1641 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1642 QTextStream ts(&file);
1643 QString line = ts.readLine();
1644 QCOMPARE(line, fileName);
1646 QString newName = fileName + QLatin1String("1");
1648 QVERIFY(QFile::copy(fileName, newName));
1649 QFile file(newName);
1650 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1651 QTextStream ts(&file);
1652 QString line = ts.readLine();
1653 QCOMPARE(line, fileName);
1656 QVERIFY(QFile::remove(newName));
1658 QVERIFY(QFile::rename(fileName, newName));
1659 QFile file(newName);
1660 QVERIFY(file.open(QFile::ReadOnly | QFile::Text));
1661 QTextStream ts(&file);
1662 QString line = ts.readLine();
1663 QCOMPARE(line, fileName);
1665 QVERIFY(QFile::exists(newName));
1666 QVERIFY(QFile::remove(newName));
1669 class MyEngine : public QAbstractFileEngine
1671 public:
1672 MyEngine(int n) { number = n; }
1673 virtual ~MyEngine() {}
1675 void setFileName(const QString &) {}
1676 bool open(int ) { return false; }
1677 bool close() { return false; }
1678 bool flush() { return false; }
1679 qint64 size() const { return 123 + number; }
1680 qint64 at() const { return -1; }
1681 bool seek(qint64) { return false; }
1682 bool isSequential() const { return false; }
1683 qint64 read(char *, qint64) { return -1; }
1684 qint64 write(const char *, qint64) { return -1; }
1685 bool remove() { return false; }
1686 bool copy(const QString &) { return false; }
1687 bool rename(const QString &) { return false; }
1688 bool link(const QString &) { return false; }
1689 bool mkdir(const QString &, bool) const { return false; }
1690 bool rmdir(const QString &, bool) const { return false; }
1691 bool setSize(qint64) { return false; }
1692 QStringList entryList(QDir::Filters, const QStringList &) const { return QStringList(); }
1693 bool caseSensitive() const { return false; }
1694 bool isRelativePath() const { return false; }
1695 FileFlags fileFlags(FileFlags) const { return 0; }
1696 bool chmod(uint) { return false; }
1697 QString fileName(FileName) const { return name; }
1698 uint ownerId(FileOwner) const { return 0; }
1699 QString owner(FileOwner) const { return QString(); }
1700 QDateTime fileTime(FileTime) const { return QDateTime(); }
1702 private:
1703 int number;
1704 QString name;
1707 class MyHandler : public QAbstractFileEngineHandler
1709 public:
1710 inline QAbstractFileEngine *create(const QString &) const
1712 return new MyEngine(1);
1716 class MyHandler2 : public QAbstractFileEngineHandler
1718 public:
1719 inline QAbstractFileEngine *create(const QString &) const
1721 return new MyEngine(2);
1725 void tst_QFile::fileEngineHandler()
1727 // A file that does not exist has a size of 0.
1728 QFile::remove("ole.bull");
1729 QFile file("ole.bull");
1730 QCOMPARE(file.size(), qint64(0));
1732 // Instantiating our handler will enable the new engine.
1733 MyHandler handler;
1734 file.setFileName("ole.bull");
1735 QCOMPARE(file.size(), qint64(124));
1737 // A new, identical handler should take preference over the last one.
1738 MyHandler2 handler2;
1739 file.setFileName("ole.bull");
1740 QCOMPARE(file.size(), qint64(125));
1744 class MyRecursiveHandler : public QAbstractFileEngineHandler
1746 public:
1747 inline QAbstractFileEngine *create(const QString &fileName) const
1749 if (fileName.startsWith(":!")) {
1750 QDir dir;
1751 QString realFile = SRCDIR + fileName.mid(2);
1752 if (dir.exists(realFile))
1753 return new QFSFileEngine(realFile);
1755 return 0;
1759 void tst_QFile::useQFileInAFileHandler()
1761 // This test should not dead-lock
1762 MyRecursiveHandler handler;
1763 QFile file(":!tst_qfile.cpp");
1764 QVERIFY(file.exists());
1767 void tst_QFile::getCharFF()
1769 QFile file("file.txt");
1770 file.open(QFile::ReadWrite);
1771 file.write("\xff\xff\xff");
1772 file.flush();
1773 file.seek(0);
1775 char c;
1776 QVERIFY(file.getChar(&c));
1777 QVERIFY(file.getChar(&c));
1778 QVERIFY(file.getChar(&c));
1781 void tst_QFile::remove_and_exists()
1783 QFile::remove("tull_i_grunn.txt");
1784 QFile f("tull_i_grunn.txt");
1786 QVERIFY(!f.exists());
1788 bool opened = f.open(QIODevice::WriteOnly);
1789 QVERIFY(opened);
1791 f.write(QString("testing that remove/exists work...").toLatin1());
1792 f.close();
1794 QVERIFY(f.exists());
1796 f.remove();
1797 QVERIFY(!f.exists());
1800 void tst_QFile::removeOpenFile()
1803 // remove an opened, write-only file
1804 QFile::remove("remove_unclosed.txt");
1805 QFile f("remove_unclosed.txt");
1807 QVERIFY(!f.exists());
1808 bool opened = f.open(QIODevice::WriteOnly);
1809 QVERIFY(opened);
1810 f.write(QString("testing that remove closes the file first...").toLatin1());
1812 bool removed = f.remove(); // remove should both close and remove the file
1813 QVERIFY(removed);
1814 QVERIFY(!f.isOpen());
1815 QVERIFY(!f.exists());
1816 QVERIFY(f.error() == QFile::NoError);
1820 // remove an opened, read-only file
1821 QFile::remove("remove_unclosed.txt");
1823 // first, write a file that we can remove
1825 QFile f("remove_unclosed.txt");
1826 QVERIFY(!f.exists());
1827 bool opened = f.open(QIODevice::WriteOnly);
1828 QVERIFY(opened);
1829 f.write(QString("testing that remove closes the file first...").toLatin1());
1830 f.close();
1833 QFile f("remove_unclosed.txt");
1834 bool opened = f.open(QIODevice::ReadOnly);
1835 QVERIFY(opened);
1836 f.readAll();
1837 // this used to only fail on FreeBSD (and Mac OS X)
1838 QVERIFY(f.flush());
1839 bool removed = f.remove(); // remove should both close and remove the file
1840 QVERIFY(removed);
1841 QVERIFY(!f.isOpen());
1842 QVERIFY(!f.exists());
1843 QVERIFY(f.error() == QFile::NoError);
1847 void tst_QFile::fullDisk()
1849 QFile file("/dev/full");
1850 if (!file.exists())
1851 QSKIP("/dev/full doesn't exist on this system", SkipAll);
1853 QVERIFY(file.open(QIODevice::WriteOnly));
1854 file.write("foobar", 6);
1856 QVERIFY(!file.flush());
1857 QCOMPARE(file.error(), QFile::ResourceError);
1858 QVERIFY(!file.flush());
1859 QCOMPARE(file.error(), QFile::ResourceError);
1861 char c = 0;
1862 file.write(&c, 0);
1863 QVERIFY(!file.flush());
1864 QCOMPARE(file.error(), QFile::ResourceError);
1865 file.write(&c, 1);
1866 QVERIFY(!file.flush());
1867 QCOMPARE(file.error(), QFile::ResourceError);
1869 file.close();
1870 QVERIFY(!file.isOpen());
1871 QCOMPARE(file.error(), QFile::ResourceError);
1872 file.open(QIODevice::WriteOnly);
1873 QCOMPARE(file.error(), QFile::NoError);
1874 file.close();
1875 QCOMPARE(file.error(), QFile::NoError);
1877 // try again without flush:
1878 QVERIFY(file.open(QIODevice::WriteOnly));
1879 file.write("foobar", 6);
1880 file.close();
1881 QVERIFY(file.error() != QFile::NoError);
1884 void tst_QFile::writeLargeDataBlock_data()
1886 QTest::addColumn<QString>("fileName");
1888 QTest::newRow("localfile") << QString("./largeblockfile.txt");
1889 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1890 // Some semi-randomness to avoid collisions.
1891 QTest::newRow("unc file")
1892 << QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
1893 .arg(QHostInfo::localHostName())
1894 .arg(QTime::currentTime().msec());
1895 #endif
1898 void tst_QFile::writeLargeDataBlock()
1900 QFETCH(QString, fileName);
1902 // Generate a 64MB array with well defined contents.
1903 QByteArray array;
1904 #if defined(Q_OS_WINCE)
1905 int resizeSize = 1024 * 1024; // WinCE does not have much space
1906 #else
1907 int resizeSize = 64 * 1024 * 1024;
1908 #endif
1909 array.resize(resizeSize);
1910 for (int i = 0; i < array.size(); ++i)
1911 array[i] = uchar(i);
1913 // Remove and open the target file
1914 QFile file(fileName);
1915 file.remove();
1916 if (file.open(QFile::WriteOnly)) {
1917 QCOMPARE(file.write(array), qint64(array.size()));
1918 file.close();
1919 QVERIFY(file.open(QFile::ReadOnly));
1920 array.clear();
1921 array = file.readAll();
1922 file.remove();
1923 } else {
1924 QFAIL(qPrintable(QString("Couldn't open file for writing: [%1]").arg(fileName)));
1926 // Check that we got the right content
1927 QCOMPARE(array.size(), resizeSize);
1928 for (int i = 0; i < array.size(); ++i) {
1929 if (array[i] != char(i)) {
1930 QFAIL(qPrintable(QString("Wrong contents! Char at %1 = %2, expected %3")
1931 .arg(i).arg(int(uchar(array[i]))).arg(int(uchar(i)))));
1936 void tst_QFile::readFromWriteOnlyFile()
1938 QFile file("writeonlyfile");
1939 QVERIFY(file.open(QFile::WriteOnly));
1940 char c;
1941 QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device");
1942 QCOMPARE(file.read(&c, 1), qint64(-1));
1945 void tst_QFile::writeToReadOnlyFile()
1947 QFile file("readonlyfile");
1948 QVERIFY(file.open(QFile::ReadOnly));
1949 char c = 0;
1950 QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device");
1951 QCOMPARE(file.write(&c, 1), qint64(-1));
1954 void tst_QFile::virtualFile()
1956 // test if QFile works with virtual files
1957 QString fname;
1958 #if defined(Q_OS_LINUX)
1959 fname = "/proc/self/maps";
1960 #elif defined(Q_OS_AIX)
1961 fname = QString("/proc/%1/map").arg(getpid());
1962 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
1963 fname = "/proc/curproc/map";
1964 #else
1965 QSKIP("This platform does not have 0-sized virtual files", SkipAll);
1966 #endif
1968 // consistency check
1969 QFileInfo fi(fname);
1970 QVERIFY(fi.exists());
1971 QVERIFY(fi.isFile());
1972 QCOMPARE(fi.size(), Q_INT64_C(0));
1974 // open the file
1975 QFile f(fname);
1976 QVERIFY(f.open(QIODevice::ReadOnly));
1977 QCOMPARE(f.size(), Q_INT64_C(0));
1978 QVERIFY(f.atEnd());
1980 // read data
1981 QByteArray data = f.read(16);
1982 QCOMPARE(data.size(), 16);
1983 QCOMPARE(f.pos(), Q_INT64_C(16));
1985 // line-reading
1986 data = f.readLine();
1987 QVERIFY(!data.isEmpty());
1989 // read all:
1990 data = f.readAll();
1991 QVERIFY(f.pos() != 0);
1992 QVERIFY(!data.isEmpty());
1994 // seeking
1995 QVERIFY(f.seek(1));
1996 QCOMPARE(f.pos(), Q_INT64_C(1));
1999 void tst_QFile::textFile()
2001 #if defined(Q_OS_WINCE)
2002 FILE *fs = ::fopen((QCoreApplication::applicationDirPath() + "/writeabletextfile").toAscii() , "wt");
2003 #elif defined(Q_OS_WIN)
2004 FILE *fs = ::fopen("writeabletextfile", "wt");
2005 #else
2006 FILE *fs = ::fopen("writeabletextfile", "w");
2007 #endif
2008 QFile f;
2009 QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n");
2010 QByteArray part2("Add\nsome\nmore\nnewlines\n");
2012 QVERIFY(f.open(fs, QIODevice::WriteOnly));
2013 f.write(part1);
2014 f.write(part2);
2015 f.close();
2016 ::fclose(fs);
2018 QFile file("writeabletextfile");
2019 QVERIFY(file.open(QIODevice::ReadOnly));
2021 QByteArray data = file.readAll();
2023 QByteArray expected = part1 + part2;
2024 #ifdef Q_OS_WIN
2025 expected.replace("\n", "\015\012");
2026 #endif
2027 QCOMPARE(data, expected);
2028 file.close();
2029 file.remove();
2032 void tst_QFile::rename_data()
2034 QTest::addColumn<QString>("source");
2035 QTest::addColumn<QString>("destination");
2036 QTest::addColumn<bool>("result");
2038 QTest::newRow("a -> b") << QString("a") << QString("b") << false;
2039 QTest::newRow("a -> .") << QString("a") << QString(".") << false;
2040 QTest::newRow("renamefile -> renamefile") << QString("renamefile") << QString("renamefile") << false;
2041 QTest::newRow("renamefile -> Makefile") << QString("renamefile") << QString("Makefile") << false;
2042 #ifdef Q_OS_UNIX
2043 QTest::newRow("renamefile -> /etc/renamefile") << QString("renamefile") << QString("/etc/renamefile") << false;
2044 #endif
2045 QTest::newRow("renamefile -> renamedfile") << QString("renamefile") << QString("renamedfile") << true;
2046 QTest::newRow("renamefile -> ..") << QString("renamefile") << QString("..") << false;
2049 void tst_QFile::rename()
2051 QFETCH(QString, source);
2052 QFETCH(QString, destination);
2053 QFETCH(bool, result);
2055 QFile::remove("renamedfile");
2056 QFile f("renamefile");
2057 f.open(QFile::WriteOnly);
2058 f.close();
2060 QFile file(source);
2061 QCOMPARE(file.rename(destination), result);
2062 if (result)
2063 QCOMPARE(file.error(), QFile::NoError);
2064 else
2065 QCOMPARE(file.error(), QFile::RenameError);
2067 QFile::remove("renamefile");
2071 \since 4.5
2073 Some special files have QFile::atEnd() returning true, even though there is
2074 more data available. True for corner cases, as well as some mounts on OS X.
2076 Here, we reproduce that condition by having a QFile sub-class with this
2077 peculiar atEnd() behavior.
2079 See task 231583.
2081 void tst_QFile::renameWithAtEndSpecialFile() const
2083 class PeculiarAtEnd : public QFile
2085 public:
2086 virtual bool atEnd() const
2088 return true;
2092 const QString newName(QLatin1String("newName.txt"));
2093 /* Cleanup, so we're a bit more robust. */
2094 QFile::remove(newName);
2096 const QString originalName(QString(SRCDIR "forRenaming.txt"));
2098 PeculiarAtEnd file;
2099 file.setFileName(originalName);
2100 QVERIFY(file.open(QIODevice::ReadOnly));
2102 QVERIFY(file.rename(newName));
2104 file.close();
2105 /* Guess what, we have to rename it back, otherwise we'll fail on second
2106 * invocation. */
2107 QVERIFY(QFile::rename(newName, originalName));
2110 void tst_QFile::renameFallback()
2112 // Using a resource file both to trigger QFile::rename's fallback handling
2113 // and as a *read-only* source whose move should fail.
2114 QFile file(":/rename-fallback.qrc");
2115 QVERIFY(file.exists() && "(test-precondition)");
2116 QFile::remove("file-rename-destination.txt");
2118 QVERIFY(!file.rename("file-rename-destination.txt"));
2119 QVERIFY(!QFile::exists("file-rename-destination.txt"));
2120 QVERIFY(!file.isOpen());
2123 void tst_QFile::renameMultiple()
2125 // create the file if it doesn't exist
2126 QFile file("file-to-be-renamed.txt");
2127 QVERIFY(file.open(QIODevice::ReadWrite) && "(test-precondition)");
2129 // any stale files from previous test failures?
2130 QFile::remove("file-renamed-once.txt");
2131 QFile::remove("file-renamed-twice.txt");
2133 // begin testing
2134 QVERIFY(file.rename("file-renamed-once.txt"));
2135 QCOMPARE(file.fileName(), QString("file-renamed-once.txt"));
2136 QVERIFY(file.rename("file-renamed-twice.txt"));
2137 QCOMPARE(file.fileName(), QString("file-renamed-twice.txt"));
2139 QVERIFY(!QFile::exists("file-to-be-renamed.txt"));
2140 QVERIFY(!QFile::exists("file-renamed-once.txt"));
2141 QVERIFY(QFile::exists("file-renamed-twice.txt"));
2143 file.remove();
2144 QVERIFY(!QFile::exists("file-renamed-twice.txt"));
2147 void tst_QFile::appendAndRead()
2149 QFile writeFile(QLatin1String("appendfile.txt"));
2150 QVERIFY(writeFile.open(QIODevice::WriteOnly | QIODevice::Truncate));
2152 QFile readFile(QLatin1String("appendfile.txt"));
2153 QVERIFY(readFile.open(QIODevice::ReadOnly));
2155 // Write to the end of the file, then read that character back, and so on.
2156 for (int i = 0; i < 100; ++i) {
2157 char c = '\0';
2158 writeFile.putChar(char(i % 256));
2159 writeFile.flush();
2160 QVERIFY(readFile.getChar(&c));
2161 QCOMPARE(c, char(i % 256));
2162 QCOMPARE(readFile.pos(), writeFile.pos());
2165 // Write blocks and read them back
2166 for (int j = 0; j < 18; ++j) {
2167 writeFile.write(QByteArray(1 << j, '@'));
2168 writeFile.flush();
2169 QCOMPARE(readFile.read(1 << j).size(), 1 << j);
2172 QFile::remove(QLatin1String("appendfile.txt"));
2175 void tst_QFile::miscWithUncPathAsCurrentDir()
2177 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2178 QString current = QDir::currentPath();
2179 QVERIFY(QDir::setCurrent("//" + QtNetworkSettings::winServerName() + "/testsharewritable"));
2180 QFile file("test.pri");
2181 QVERIFY(file.exists());
2182 QCOMPARE(int(file.size()), 34);
2183 QVERIFY(file.open(QIODevice::ReadOnly));
2184 QVERIFY(QDir::setCurrent(current));
2185 #endif
2188 void tst_QFile::standarderror()
2190 QFile f;
2191 bool ok = f.open(stderr, QFile::WriteOnly);
2192 QVERIFY(ok);
2193 f.close();
2196 void tst_QFile::handle()
2198 #ifndef Q_OS_WINCE
2199 QFile file(SRCDIR "tst_qfile.cpp");
2200 QVERIFY(file.open(QIODevice::ReadOnly));
2201 int fd = int(file.handle());
2202 QVERIFY(fd > 2);
2203 QCOMPARE(int(file.handle()), fd);
2204 char c = '\0';
2205 QT_READ(int(file.handle()), &c, 1);
2206 QCOMPARE(c, '/');
2208 // test if the QFile and the handle remain in sync
2209 QVERIFY(file.getChar(&c));
2210 QCOMPARE(c, '*');
2212 // same, but read from QFile first now
2213 file.close();
2214 QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Unbuffered));
2215 fd = int(file.handle());
2216 QVERIFY(fd > 2);
2217 QVERIFY(file.getChar(&c));
2218 QCOMPARE(c, '/');
2219 #ifdef Q_OS_UNIX
2220 QCOMPARE(QT_READ(fd, &c, 1), ssize_t(1));
2221 #else
2222 QCOMPARE(QT_READ(fd, &c, 1), 1);
2223 #endif
2225 QCOMPARE(c, '*');
2226 #endif
2228 QFile file2;
2229 FILE *fp = fopen(SRCDIR "tst_qfile.cpp", "r");
2230 file2.open(fp, QIODevice::ReadOnly);
2231 QCOMPARE(int(file2.handle()), int(fileno(fp)));
2232 QCOMPARE(int(file2.handle()), int(fileno(fp)));
2233 fclose(fp);
2235 #ifdef Q_OS_UNIX
2236 QFile file3;
2237 fd = QT_OPEN(SRCDIR "tst_qfile.cpp", QT_OPEN_RDONLY);
2238 file3.open(fd, QIODevice::ReadOnly);
2239 QCOMPARE(int(file3.handle()), fd);
2240 QT_CLOSE(fd);
2241 #endif
2244 void tst_QFile::readEof_data()
2246 QTest::addColumn<QString>("filename");
2247 QTest::addColumn<int>("imode");
2249 QTest::newRow("buffered") << SRCDIR "testfile.txt" << 0;
2250 QTest::newRow("unbuffered") << SRCDIR "testfile.txt" << int(QIODevice::Unbuffered);
2252 #ifdef Q_OS_UNIX
2253 QTest::newRow("sequential,buffered") << "/dev/null" << 0;
2254 QTest::newRow("sequential,unbuffered") << "/dev/null" << int(QIODevice::Unbuffered);
2255 #endif
2258 void tst_QFile::readEof()
2260 QFETCH(QString, filename);
2261 QFETCH(int, imode);
2262 QIODevice::OpenMode mode = QIODevice::OpenMode(imode);
2265 QFile file(filename);
2266 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2267 bool isSequential = file.isSequential();
2268 if (!isSequential) {
2269 QVERIFY(file.seek(245));
2270 QVERIFY(file.atEnd());
2273 char buf[10];
2274 int ret = file.read(buf, sizeof buf);
2275 QCOMPARE(ret, 0);
2276 QVERIFY(file.error() == QFile::NoError);
2277 QVERIFY(file.atEnd());
2279 // Do it again to ensure that we get the same result
2280 ret = file.read(buf, sizeof buf);
2281 QCOMPARE(ret, 0);
2282 QVERIFY(file.error() == QFile::NoError);
2283 QVERIFY(file.atEnd());
2287 QFile file(filename);
2288 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2289 bool isSequential = file.isSequential();
2290 if (!isSequential) {
2291 QVERIFY(file.seek(245));
2292 QVERIFY(file.atEnd());
2295 QByteArray ret = file.read(10);
2296 QVERIFY(ret.isNull());
2297 QVERIFY(file.error() == QFile::NoError);
2298 QVERIFY(file.atEnd());
2300 // Do it again to ensure that we get the same result
2301 ret = file.read(10);
2302 QVERIFY(ret.isNull());
2303 QVERIFY(file.error() == QFile::NoError);
2304 QVERIFY(file.atEnd());
2308 QFile file(filename);
2309 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2310 bool isSequential = file.isSequential();
2311 if (!isSequential) {
2312 QVERIFY(file.seek(245));
2313 QVERIFY(file.atEnd());
2316 char buf[10];
2317 int ret = file.readLine(buf, sizeof buf);
2318 QCOMPARE(ret, -1);
2319 QVERIFY(file.error() == QFile::NoError);
2320 QVERIFY(file.atEnd());
2322 // Do it again to ensure that we get the same result
2323 ret = file.readLine(buf, sizeof buf);
2324 QCOMPARE(ret, -1);
2325 QVERIFY(file.error() == QFile::NoError);
2326 QVERIFY(file.atEnd());
2330 QFile file(filename);
2331 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2332 bool isSequential = file.isSequential();
2333 if (!isSequential) {
2334 QVERIFY(file.seek(245));
2335 QVERIFY(file.atEnd());
2338 QByteArray ret = file.readLine();
2339 QVERIFY(ret.isNull());
2340 QVERIFY(file.error() == QFile::NoError);
2341 QVERIFY(file.atEnd());
2343 // Do it again to ensure that we get the same result
2344 ret = file.readLine();
2345 QVERIFY(ret.isNull());
2346 QVERIFY(file.error() == QFile::NoError);
2347 QVERIFY(file.atEnd());
2351 QFile file(filename);
2352 QVERIFY(file.open(QIODevice::ReadOnly | mode));
2353 bool isSequential = file.isSequential();
2354 if (!isSequential) {
2355 QVERIFY(file.seek(245));
2356 QVERIFY(file.atEnd());
2359 char c;
2360 QVERIFY(!file.getChar(&c));
2361 QVERIFY(file.error() == QFile::NoError);
2362 QVERIFY(file.atEnd());
2364 // Do it again to ensure that we get the same result
2365 QVERIFY(!file.getChar(&c));
2366 QVERIFY(file.error() == QFile::NoError);
2367 QVERIFY(file.atEnd());
2371 void tst_QFile::task167217()
2373 // Regression introduced in 4.3.0; after a failed stat, pos() could no
2374 // longer be calculated correctly.
2375 QFile::remove("tmp.txt");
2376 QFile file("tmp.txt");
2377 QVERIFY(!file.exists());
2378 QVERIFY(file.open(QIODevice::Append));
2379 QVERIFY(file.exists());
2380 file.write("qt430", 5);
2381 QVERIFY(!file.isSequential());
2382 QCOMPARE(file.pos(), qint64(5));
2383 file.remove();
2386 #define FILESIZE 65536 * 3
2388 void tst_QFile::map_data()
2390 QTest::addColumn<int>("fileSize");
2391 QTest::addColumn<int>("offset");
2392 QTest::addColumn<int>("size");
2393 QTest::addColumn<QFile::FileError>("error");
2395 QTest::newRow("zero") << FILESIZE << 0 << FILESIZE << QFile::NoError;
2396 QTest::newRow("small, but 0") << FILESIZE << 30 << FILESIZE - 30 << QFile::NoError;
2397 QTest::newRow("a page") << FILESIZE << 4096 << FILESIZE - 4096 << QFile::NoError;
2398 QTest::newRow("+page") << FILESIZE << 5000 << FILESIZE - 5000 << QFile::NoError;
2399 QTest::newRow("++page") << FILESIZE << 65576 << FILESIZE - 65576 << QFile::NoError;
2400 QTest::newRow("bad size") << FILESIZE << 0 << -1 << QFile::ResourceError;
2401 QTest::newRow("bad offset") << FILESIZE << -1 << 1 << QFile::UnspecifiedError;
2402 QTest::newRow("zerozero") << FILESIZE << 0 << 0 << QFile::UnspecifiedError;
2405 void tst_QFile::map()
2407 QFETCH(int, fileSize);
2408 QFETCH(int, offset);
2409 QFETCH(int, size);
2410 QFETCH(QFile::FileError, error);
2412 QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
2413 if (QFile::exists(fileName)) {
2414 QVERIFY(QFile::setPermissions(fileName,
2415 QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
2416 QFile::remove(fileName);
2418 QFile file(fileName);
2420 // invalid, not open
2421 uchar *memory = file.map(0, size);
2422 QVERIFY(!memory);
2423 QCOMPARE(file.error(), QFile::PermissionsError);
2424 QVERIFY(!file.unmap(memory));
2425 QCOMPARE(file.error(), QFile::PermissionsError);
2427 // make a file
2428 QVERIFY(file.open(QFile::ReadWrite));
2429 QVERIFY(file.resize(fileSize));
2430 QVERIFY(file.flush());
2431 file.close();
2432 QVERIFY(file.open(QFile::ReadWrite));
2433 memory = file.map(offset, size);
2434 if (error != QFile::NoError) {
2435 QVERIFY(file.error() != QFile::NoError);
2436 return;
2438 QCOMPARE(file.error(), error);
2439 QVERIFY(memory);
2440 memory[0] = 'Q';
2441 QVERIFY(file.unmap(memory));
2442 QCOMPARE(file.error(), QFile::NoError);
2444 // Verify changes were saved
2445 memory = file.map(offset, size);
2446 QCOMPARE(file.error(), QFile::NoError);
2447 QVERIFY(memory);
2448 QVERIFY(memory[0] == 'Q');
2449 QVERIFY(file.unmap(memory));
2450 QCOMPARE(file.error(), QFile::NoError);
2452 // hpux wont let you map multiple times.
2453 #if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API)
2454 // exotic test to make sure that multiple maps work
2455 uchar *memory1 = file.map(0, file.size());
2456 QCOMPARE(file.error(), QFile::NoError);
2457 uchar *memory2 = file.map(0, file.size());
2458 QCOMPARE(file.error(), QFile::NoError);
2459 QVERIFY(memory1);
2460 QVERIFY(memory2);
2461 QVERIFY(file.unmap(memory1));
2462 QCOMPARE(file.error(), QFile::NoError);
2463 QVERIFY(file.unmap(memory2));
2464 QCOMPARE(file.error(), QFile::NoError);
2465 memory1 = file.map(0, file.size());
2466 QCOMPARE(file.error(), QFile::NoError);
2467 QVERIFY(memory1);
2468 QVERIFY(file.unmap(memory1));
2469 QCOMPARE(file.error(), QFile::NoError);
2470 #endif
2472 file.close();
2474 // Change permissions on a file, just to confirm it would fail
2475 QFile::Permissions originalPermissions = file.permissions();
2476 QVERIFY(file.setPermissions(QFile::ReadOther));
2477 QVERIFY(!file.open(QFile::ReadWrite));
2478 memory = file.map(offset, size);
2479 QCOMPARE(file.error(), QFile::PermissionsError);
2480 QVERIFY(!memory);
2481 QVERIFY(file.setPermissions(originalPermissions));
2483 QVERIFY(file.remove());
2486 void tst_QFile::mapResource_data()
2488 QTest::addColumn<int>("offset");
2489 QTest::addColumn<int>("size");
2490 QTest::addColumn<QFile::FileError>("error");
2491 QTest::addColumn<QString>("fileName");
2493 QString validFile = ":/tst_qfileinfo/resources/file1.ext1";
2494 QString invalidFile = ":/tst_qfileinfo/resources/filefoo.ext1";
2496 for (int i = 0; i < 2; ++i) {
2497 QString file = (i == 0) ? validFile : invalidFile;
2498 QTest::newRow("0, 0") << 0 << 0 << QFile::UnspecifiedError << file;
2499 QTest::newRow("0, BIG") << 0 << 4096 << QFile::UnspecifiedError << file;
2500 QTest::newRow("-1, 0") << -1 << 0 << QFile::UnspecifiedError << file;
2501 QTest::newRow("0, -1") << 0 << -1 << QFile::UnspecifiedError << file;
2504 QTest::newRow("0, 1") << 0 << 1 << QFile::NoError << validFile;
2507 void tst_QFile::mapResource()
2509 QFETCH(QString, fileName);
2510 QFETCH(int, offset);
2511 QFETCH(int, size);
2512 QFETCH(QFile::FileError, error);
2514 QFile file(fileName);
2515 uchar *memory = file.map(offset, size);
2516 QCOMPARE(file.error(), error);
2517 QVERIFY((error == QFile::NoError) ? (memory != 0) : (memory == 0));
2518 if (error == QFile::NoError)
2519 QCOMPARE(QString(memory[0]), QString::number(offset + 1));
2520 QVERIFY(file.unmap(memory));
2523 void tst_QFile::mapOpenMode_data()
2525 QTest::addColumn<int>("openMode");
2527 QTest::newRow("ReadOnly") << int(QIODevice::ReadOnly);
2528 //QTest::newRow("WriteOnly") << int(QIODevice::WriteOnly); // this doesn't make sense
2529 QTest::newRow("ReadWrite") << int(QIODevice::ReadWrite);
2530 QTest::newRow("ReadOnly,Unbuffered") << int(QIODevice::ReadOnly | QIODevice::Unbuffered);
2531 QTest::newRow("ReadWrite,Unbuffered") << int(QIODevice::ReadWrite | QIODevice::Unbuffered);
2534 void tst_QFile::mapOpenMode()
2536 QFETCH(int, openMode);
2537 static const qint64 fileSize = 4096;
2538 QByteArray pattern(fileSize, 'A');
2540 QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile";
2541 if (QFile::exists(fileName)) {
2542 QVERIFY(QFile::setPermissions(fileName,
2543 QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser));
2544 QFile::remove(fileName);
2546 QFile file(fileName);
2548 // make a file
2549 QVERIFY(file.open(QFile::ReadWrite));
2550 QVERIFY(file.write(pattern));
2551 QVERIFY(file.flush());
2552 file.close();
2554 // open according to our mode
2555 QVERIFY(file.open(QIODevice::OpenMode(openMode)));
2557 uchar *memory = file.map(0, fileSize);
2558 QVERIFY(memory);
2559 QVERIFY(memcmp(memory, pattern, fileSize) == 0);
2561 if (openMode & QIODevice::WriteOnly) {
2562 // try to write to the file
2563 *memory = 'a';
2564 file.unmap(memory);
2565 file.close();
2566 file.open(QIODevice::OpenMode(openMode));
2567 file.seek(0);
2568 char c;
2569 QVERIFY(file.getChar(&c));
2570 QCOMPARE(c, 'a');
2573 file.close();
2576 void tst_QFile::openDirectory()
2578 QFile f1("resources");
2579 QVERIFY(!f1.open(QIODevice::ReadOnly));
2580 f1.close();
2581 QVERIFY(!f1.open(QIODevice::ReadOnly|QIODevice::Unbuffered));
2584 QTEST_MAIN(tst_QFile)
2585 #include "tst_qfile.moc"