1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
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
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.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
44 #include <qplatformdefs.h>
46 #include <QAbstractFileEngine>
47 #include <QFSFileEngine>
48 #include <QCoreApplication>
53 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
58 # include <sys/types.h>
62 # include <sys/mount.h>
63 #elif defined(Q_OS_LINUX)
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>
76 #include "../network-settings.h"
78 #if defined(Q_OS_SYMBIAN)
83 #define STDIN_FILENO 0
87 #define STDOUT_FILENO 1
91 #define STDERR_FILENO 2
94 #ifndef QT_OPEN_BINARY
95 #define QT_OPEN_BINARY 0
98 Q_DECLARE_METATYPE(QFile::FileError
)
103 class tst_QFile
: public QObject
109 virtual ~tst_QFile();
117 void cleanupTestCase();
121 void openUnbuffered();
131 void readLineNullInLine();
133 void readLineStdin();
134 void readLineStdin_lineByLine();
136 void missingEndOfLine();
142 void permissions_data();
144 void setPermissions();
146 void copyAfterFail();
147 void copyRemovesTemporaryFile() const;
148 void copyShouldntOverwrite();
152 void absolutePathLinkToRelativePath();
153 void readBrokenLink();
154 void readTextFile_data();
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();
170 void FILEReadWrite();
171 void i18nFileName_data();
173 void longFileName_data();
175 void fileEngineHandler();
176 void useQFileInAFileHandler();
178 void remove_and_exists();
179 void removeOpenFile();
181 void writeLargeDataBlock_data();
182 void writeLargeDataBlock();
183 void readFromWriteOnlyFile();
184 void writeToReadOnlyFile();
189 void renameWithAtEndSpecialFile() const;
190 void renameFallback();
191 void renameMultiple();
192 void appendAndRead();
193 void miscWithUncPathAsCurrentDir();
194 void standarderror();
202 void mapResource_data();
204 void mapOpenMode_data();
207 void openStandardStreams();
209 // --- Task related tests below this line
212 void openDirectory();
216 // disabled this test for the moment... it hangs
217 void invalidFile_data();
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
)
245 else if (mode
& QIODevice::ReadOnly
)
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
))
263 // Note: openFd and openStream will truncate the file if write mode.
267 return file
.open(mode
);
270 return openFd(file
, mode
);
273 return openStream(file
, mode
);
279 void closeFile(QFile
&file
)
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.
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");
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
);
355 file
.setPermissions(QFile::ReadOwner
);
357 // create another file and make it not readable
358 file
.setFileName("noreadfile");
359 file
.open(QFile::WriteOnly
);
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");
406 QVERIFY(!file
.exists());
408 QFile
file2("nobodyhassuchafile");
409 QVERIFY(file2
.open(QIODevice::WriteOnly
));
412 QVERIFY(file
.exists());
414 QVERIFY(file
.open(QIODevice::WriteOnly
));
416 QVERIFY(file
.exists());
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());
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");
435 static const QString
denied("Operation not permitted");
437 static const QString
denied("Permission denied");
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
)
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")
459 << int(QIODevice::ReadOnly
)
463 QTest::newRow("nullfile") << QString() << int(QIODevice::ReadOnly
) << (bool)FALSE
466 QTest::newRow("two-dots") << QString(SRCDIR
"two.dots.file") << int(QIODevice::ReadOnly
) << (bool)TRUE
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
;
481 void tst_QFile::open()
483 QFETCH( QString
, filename
);
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)
495 // root and Chuck Norris don't care for file permissions. Skip.
496 QSKIP("Running this test as root doesn't make sense", SkipAll
);
499 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
500 QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort
);
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
));
515 QVERIFY(file
.seek(1));
516 QCOMPARE(file
.pos(), qint64(1));
517 QVERIFY(file
.getChar(&c
));
518 QCOMPARE(file
.pos(), qint64(2));
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));
527 QVERIFY(file
.getChar(&c2
));
528 QCOMPARE(file
.pos(), qint64(2));
529 QVERIFY(file
.seek(3));
530 QCOMPARE(file
.pos(), qint64(3));
532 QVERIFY(file
.getChar(&d2
));
533 QCOMPARE(file
.pos(), qint64(4));
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;
552 void tst_QFile::size()
554 QFETCH( QString
, filename
);
555 QFETCH( qint64
, size
);
559 QCOMPARE( f
.size(), size
);
561 QVERIFY( f
.open(QIODevice::ReadOnly
) );
562 QCOMPARE( f
.size(), size
);
567 int fd
= QT_OPEN(filename
.toLocal8Bit().constData(), QT_OPEN_RDONLY
);
569 QVERIFY( f
.open(fd
, QIODevice::ReadOnly
) );
570 QCOMPARE( f
.size(), size
);
578 FILE* stream
= QT_FOPEN(filename
.toLocal8Bit().constData(), "rb");
580 QVERIFY( f
.open(stream
, QIODevice::ReadOnly
) );
581 QCOMPARE( f
.size(), size
);
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
));
626 QCOMPARE(f
.size(), (qlonglong
)1);
627 bool ok
= f
.resize(99);
629 QCOMPARE(f
.size(), (qlonglong
)99);
636 QVERIFY(f
.resize(1));
637 QCOMPARE(f
.size(), (qlonglong
)1);
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
));
660 QCOMPARE(f
.pos(), qint64(4));
662 QCOMPARE(f
.pos(), qint64(2));
664 QCOMPARE(f
.pos(), qint64(2));
666 QCOMPARE(f
.pos(), qint64(0));
668 QCOMPARE(f
.pos(), qint64(0));
671 QCOMPARE(f
.pos(), qint64(3));
673 QCOMPARE(f
.pos(), qint64(2));
676 void tst_QFile::atEnd()
678 QFile
f( SRCDIR
"testfile.txt" );
679 QVERIFY(f
.open( QIODevice::ReadOnly
));
684 bool end
= f
.atEnd();
686 QCOMPARE( end
, (bool)TRUE
);
689 void tst_QFile::readLine()
691 QFile
f( SRCDIR
"testfile.txt" );
692 QVERIFY(f
.open( QIODevice::ReadOnly
));
697 while ( (foo
=f
.readLine( p
, 128 )) > 0 ) {
700 QCOMPARE( p
[0], 'T' );
701 QCOMPARE( p
[3], 's' );
702 QCOMPARE( p
[11], 'i' );
709 void tst_QFile::readLine2()
711 QFile
f( SRCDIR
"testfile.txt" );
712 f
.open( QIODevice::ReadOnly
);
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());
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
);
747 #if defined(QT_NO_PROCESS)
748 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll
);
750 QByteArray
lotsOfData(1024, '@'); // 10 megs
753 process
.start("stdinprocess/stdinprocess all");
754 QVERIFY( process
.waitForStarted() );
755 for (int i
= 0; i
< 5; ++i
) {
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);
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
);
774 #if defined(QT_NO_PROCESS)
775 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll
);
778 QByteArray
lotsOfData(1024, '@'); // 10 megs
779 for (int i
= 0; i
< lotsOfData
.size(); ++i
) {
781 lotsOfData
[i
] = '\n';
783 lotsOfData
[i
] = char('0' + i
% 32);
786 for (int i
= 0; i
< 2; ++i
) {
788 process
.start(QString("stdinprocess/stdinprocess line %1").arg(i
), QIODevice::Text
| QIODevice::ReadWrite
);
789 for (int i
= 0; i
< 5; ++i
) {
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
) {
804 QCOMPARE(char(array
[i
]), '\n');
806 QCOMPARE(char(array
[i
]), char('0' + i
% 32));
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
);
817 #if defined(QT_NO_PROCESS)
818 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll
);
820 for (int i
= 0; i
< 2; ++i
) {
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));
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');
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
));
860 while (!file
.atEnd()) {
868 void tst_QFile::readBlock()
870 QFile
f( SRCDIR
"testfile.txt" );
871 f
.open( QIODevice::ReadOnly
);
875 length
= f
.read( p
, 256 );
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
);
890 while (f
.getChar(&c
)) {
891 QCOMPARE(f
.pos(), qint64(i
+ 1));
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");
909 array
= f
.readLine();
910 QCOMPARE(array
.constData(), "\n");
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
));
924 QCOMPARE(out
.readAll().constData(), "123");
928 QCOMPARE(out
.readAll().constData(), "124");
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//" );
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" );
958 void tst_QFile::invalidFile()
960 QFETCH( QString
, 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
) );
974 QVERIFY( QFile::exists( "createme.txt" ) );
977 void tst_QFile::append()
979 const QString
name("appendme.txt");
980 if (QFile::exists(name
))
982 QVERIFY(!QFile::exists(name
));
985 QVERIFY(f
.open(QIODevice::WriteOnly
| QIODevice::Truncate
));
989 QVERIFY(f
.open(QIODevice::Append
));
990 QVERIFY(f
.pos() == 1);
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
);
1016 QFETCH(QString
, file
);
1017 QFETCH(uint
, perms
);
1018 QFETCH(bool, expected
);
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
));
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)");
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
);
1110 bool ok
= QFile::setPermissions("tst_qfile.cpy", QFile::WriteOther
);
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");
1146 #include <objbase.h>
1150 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1151 static QString
getWorkingDirectoryForLink(const QString
&linkFileName
)
1153 bool neededCoInit
= false;
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;
1161 hres
= CoCreateInstance(CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
, IID_IShellLink
, (void **)&psl
);
1164 if (SUCCEEDED(hres
)) { // Get pointer to the IPersistFile interface.
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
);
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());
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
);
1210 QFile::remove("myLinkToDir.lnk");
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
1220 QVERIFY(info2
.isSymLink());
1222 QCOMPARE(info2
.symLinkTarget(), info1
.absoluteFilePath());
1223 QVERIFY(QFile::remove(info2
.absoluteFilePath()));
1224 QFile::remove("myLinkToDir.lnk");
1228 void tst_QFile::absolutePathLinkToRelativePath()
1230 QFile::remove("myDir/test.txt");
1231 QFile::remove("myDir/myLink.lnk");
1234 QFile("myDir/test.txt").open(QFile::WriteOnly
);
1237 QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk"));
1239 QVERIFY(QFile::link("myDir/test.txt", "myDir/myLink.lnk"));
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");
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");
1261 QVERIFY(QFile::link("file12", "myLink2.lnk"));
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());
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
));
1299 QVERIFY(winfile
.open(QFile::ReadOnly
));
1300 QCOMPARE(winfile
.readAll(), in
);
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
));
1316 QFile
file(SRCDIR
"testlog.txt");
1317 QVERIFY(file
.open(QIODevice::ReadOnly
| QIODevice::Text
));
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
;
1347 out
.replace('\n', "\r\n");
1349 QCOMPARE(file
.write(in
), qlonglong(in
.size()));
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
);
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
);
1387 // 3) stdio file handling.
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
);
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()));
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");
1459 #if defined(Q_OS_WINCE)
1460 FILE *stdFile
= fopen((QCoreApplication::applicationDirPath() + "/stdfile.txt").toAscii() , "r");
1462 FILE *stdFile
= fopen("stdfile.txt", "r");
1466 QCOMPARE(int(fread(&c
, 1, 1, stdFile
)), 1);
1468 QCOMPARE(int(ftell(stdFile
)), 1);
1472 QVERIFY(file
.open(stdFile
, QFile::ReadOnly
));
1473 QCOMPARE(file
.pos(), qlonglong(1));
1474 QCOMPARE(file
.read(&c
, 1), qlonglong(1));
1476 QCOMPARE(file
.pos(), qlonglong(2));
1482 void tst_QFile::isSequential()
1484 #if defined (Q_OS_WIN) || defined(Q_OS_SYMBIAN)
1485 QSKIP("Unix only test.", SkipAll
);
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, '@'));
1506 QVERIFY(file
.open((i
? QFile::WriteOnly
: QFile::ReadWrite
) | QFile::Truncate
));
1507 file
.write(QByteArray(100, '$'));
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");
1524 QFile
file("seekToPos.txt");
1525 QVERIFY(file
.open(QFile::ReadOnly
| QFile::Text
));
1528 QVERIFY(file
.getChar(&c
));
1531 QCOMPARE(file
.pos(), qint64(3));
1532 file
.seek(file
.pos());
1533 QCOMPARE(file
.pos(), qint64(3));
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");
1551 QFile
f("FILEReadWrite.txt");
1552 QVERIFY(f
.open(QFile::WriteOnly
));
1582 FILE *fp
= fopen(qPrintable(QCoreApplication::applicationDirPath() + "\\FILEReadWrite.txt"), "r+b");
1584 FILE *fp
= fopen("FILEReadWrite.txt", "r+b");
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);
1598 QCOMPARE(file
.pos(), base
+ 1);
1599 file
.flush(); // flushing should not change the base
1600 QCOMPARE(file
.pos(), base
+ 1);
1602 QCOMPARE(file
.pos(), base
+ 2);
1604 QCOMPARE(file
.pos(), base
+ 3);
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);
1622 // check modified file
1624 QFile
f("FILEReadWrite.txt");
1625 QVERIFY(f
.open(QFile::ReadOnly
));
1629 QCOMPARE(c
, (qint8
)5);
1631 QCOMPARE(c
, (qint8
)6);
1633 QCOMPARE(c
, (qint8
)7);
1635 QCOMPARE(c
, (qint8
)8);
1637 QCOMPARE(c
, (qint8
)9);
1639 QCOMPARE(c
, (qint8
)10);
1641 QCOMPARE(c
, (qint8
)11);
1643 QCOMPARE(c
, (qint8
)12);
1645 QCOMPARE(c
, (qint8
)13);
1647 QCOMPARE(c
, (qint8
)14);
1649 QCOMPARE(c
, (qint8
)15);
1651 QCOMPARE(c
, (qint8
)16);
1655 QFile::remove("FILEReadWrite.txt");
1660 #include <qglobal.h>
1662 #define FILESIZE 0x10000000f
1663 void tst_QFile::largeFileSupport()
1666 QSKIP("Solaris does not support statfs", SkipAll);
1668 qlonglong sizeNeeded = 2147483647;
1671 qlonglong freespace = qlonglong(0);
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)
1679 if (statfs(QDir::currentPath().local8Bit(), &info, sizeof(struct statfs), 0) == 0) {
1680 freespace = qlonglong(info.f_bfree * info.f_bsize);
1683 if (statfs(const_cast<char *>(QDir::currentPath().toLocal8Bit().constData()), &info) == 0) {
1684 freespace = qlonglong(info.f_bavail * info.f_bsize);
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);
1698 if (bigFile.open(QFile::ReadOnly)) {
1699 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
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');
1708 QVERIFY(bigFile.remove());
1710 QVERIFY(bigFile.remove());
1711 QFAIL("Could not reopen file");
1714 QFAIL("Could not open file");
1717 QSKIP("Not enough space to run test", SkipSingle);
1720 QFAIL("Could not determin disk space");
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
);
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
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(); }
1869 class MyHandler
: public QAbstractFileEngineHandler
1872 inline QAbstractFileEngine
*create(const QString
&) const
1874 return new MyEngine(1);
1878 class MyHandler2
: public QAbstractFileEngineHandler
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.
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
1909 inline QAbstractFileEngine
*create(const QString
&fileName
) const
1911 if (fileName
.startsWith(":!")) {
1913 QString realFile
= SRCDIR
+ fileName
.mid(2);
1914 if (dir
.exists(realFile
))
1915 return new QFSFileEngine(realFile
);
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");
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
);
1953 f
.write(QString("testing that remove/exists work...").toLatin1());
1956 QVERIFY(f
.exists());
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
);
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
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
);
1991 f
.write(QString("testing that remove closes the file first...").toLatin1());
1995 QFile
f("remove_unclosed.txt");
1996 bool opened
= f
.open(QIODevice::ReadOnly
);
1999 // this used to only fail on FreeBSD (and Mac OS X)
2001 bool removed
= f
.remove(); // remove should both close and remove the file
2003 QVERIFY(!f
.isOpen());
2004 QVERIFY(!f
.exists());
2005 QVERIFY(f
.error() == QFile::NoError
);
2009 void tst_QFile::fullDisk()
2011 QFile
file("/dev/full");
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
);
2025 QVERIFY(!file
.flush());
2026 QCOMPARE(file
.error(), QFile::ResourceError
);
2028 QVERIFY(!file
.flush());
2029 QCOMPARE(file
.error(), QFile::ResourceError
);
2032 QVERIFY(!file
.isOpen());
2033 QCOMPARE(file
.error(), QFile::ResourceError
);
2034 file
.open(QIODevice::WriteOnly
);
2035 QCOMPARE(file
.error(), QFile::NoError
);
2037 QCOMPARE(file
.error(), QFile::NoError
);
2039 // try again without flush:
2040 QVERIFY(file
.open(QIODevice::WriteOnly
));
2041 file
.write("foobar", 6);
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
;
2064 static QByteArray
getLargeDataBlock()
2066 static QByteArray array
;
2070 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
2071 int resizeSize
= 1024 * 1024; // WinCE and Symbian do not have much space
2073 int resizeSize
= 64 * 1024 * 1024;
2075 array
.resize(resizeSize
);
2076 for (int i
= 0; i
< array
.size(); ++i
)
2077 array
[i
] = uchar(i
);
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() );
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();
2112 QCOMPARE( readData
, originalData
);
2113 QVERIFY( QFile::remove(fileName
) );
2116 void tst_QFile::readFromWriteOnlyFile()
2118 QFile
file("writeonlyfile");
2119 QVERIFY(file
.open(QFile::WriteOnly
));
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
));
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
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";
2145 QSKIP("This platform does not have 0-sized virtual files", SkipAll
);
2148 // consistency check
2149 QFileInfo
fi(fname
);
2150 QVERIFY(fi
.exists());
2151 QVERIFY(fi
.isFile());
2152 QCOMPARE(fi
.size(), Q_INT64_C(0));
2156 QVERIFY(f
.open(QIODevice::ReadOnly
));
2157 QCOMPARE(f
.size(), Q_INT64_C(0));
2161 QByteArray data
= f
.read(16);
2162 QCOMPARE(data
.size(), 16);
2163 QCOMPARE(f
.pos(), Q_INT64_C(16));
2166 data
= f
.readLine();
2167 QVERIFY(!data
.isEmpty());
2171 QVERIFY(f
.pos() != 0);
2172 QVERIFY(!data
.isEmpty());
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");
2186 FILE *fs
= ::fopen("writeabletextfile", "w");
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
));
2198 QFile
file("writeabletextfile");
2199 QVERIFY(file
.open(QIODevice::ReadOnly
));
2201 QByteArray data
= file
.readAll();
2203 QByteArray expected
= part1
+ part2
;
2205 expected
.replace("\n", "\015\012");
2207 QCOMPARE(data
, expected
);
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;
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
);
2241 QCOMPARE(file
.rename(destination
), result
);
2243 QCOMPARE(file
.error(), QFile::NoError
);
2245 QCOMPARE(file
.error(), QFile::RenameError
);
2247 QFile::remove("renamefile");
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.
2261 void tst_QFile::renameWithAtEndSpecialFile() const
2263 class PeculiarAtEnd
: public QFile
2266 virtual bool atEnd() const
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"));
2279 file
.setFileName(originalName
);
2280 QVERIFY(file
.open(QIODevice::ReadOnly
));
2282 QVERIFY(file
.rename(newName
));
2285 /* Guess what, we have to rename it back, otherwise we'll fail on second
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");
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"));
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
) {
2356 writeFile
.putChar(char(i
% 256));
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
, '@'));
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
));
2386 void tst_QFile::standarderror()
2389 bool ok
= f
.open(stderr
, QFile::WriteOnly
);
2394 void tst_QFile::handle()
2397 QFile
file(SRCDIR
"tst_qfile.cpp");
2398 QVERIFY(file
.open(QIODevice::ReadOnly
));
2399 int fd
= int(file
.handle());
2401 QCOMPARE(int(file
.handle()), fd
);
2403 QT_READ(int(file
.handle()), &c
, 1);
2406 // test if the QFile and the handle remain in sync
2407 QVERIFY(file
.getChar(&c
));
2410 // same, but read from QFile first now
2412 QVERIFY(file
.open(QIODevice::ReadOnly
| QIODevice::Unbuffered
));
2413 fd
= int(file
.handle());
2415 QVERIFY(file
.getChar(&c
));
2418 QCOMPARE(QT_READ(fd
, &c
, 1), ssize_t(1));
2420 QCOMPARE(QT_READ(fd
, &c
, 1), 1);
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
)));
2435 fd
= QT_OPEN(SRCDIR
"tst_qfile.cpp", QT_OPEN_RDONLY
);
2436 file3
.open(fd
, QIODevice::ReadOnly
);
2437 QCOMPARE(int(file3
.handle()), fd
);
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
);
2456 void tst_QFile::readEof()
2458 QFETCH(QString
, filename
);
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());
2472 int ret
= file
.read(buf
, sizeof buf
);
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
);
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());
2515 int ret
= file
.readLine(buf
, sizeof buf
);
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
);
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());
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));
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
);
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
);
2621 QCOMPARE(file
.error(), QFile::PermissionsError
);
2622 QVERIFY(!file
.unmap(memory
));
2623 QCOMPARE(file
.error(), QFile::PermissionsError
);
2626 QVERIFY(file
.open(QFile::ReadWrite
));
2627 QVERIFY(file
.resize(fileSize
));
2628 QVERIFY(file
.flush());
2630 QVERIFY(file
.open(QFile::ReadWrite
));
2631 memory
= file
.map(offset
, size
);
2632 if (error
!= QFile::NoError
) {
2634 QVERIFY(file
.error() != QFile::NoError
);
2638 QCOMPARE(file
.error(), error
);
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
);
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
);
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
);
2668 QVERIFY(file
.unmap(memory1
));
2669 QCOMPARE(file
.error(), QFile::NoError
);
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
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
);
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
);
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
);
2757 QVERIFY(file
.open(QFile::ReadWrite
));
2758 QVERIFY(file
.write(pattern
));
2759 QVERIFY(file
.flush());
2762 // open according to our mode
2763 QVERIFY(file
.open(QIODevice::OpenMode(openMode
)));
2765 uchar
*memory
= file
.map(0, fileSize
);
2767 QVERIFY(memcmp(memory
, pattern
, fileSize
) == 0);
2769 if (openMode
& QIODevice::WriteOnly
) {
2770 // try to write to the file
2774 file
.open(QIODevice::OpenMode(openMode
));
2777 QVERIFY(file
.getChar(&c
));
2784 void tst_QFile::openDirectory()
2786 QFile
f1("resources");
2787 QVERIFY(!f1
.open(QIODevice::ReadOnly
));
2789 QVERIFY(!f1
.open(QIODevice::ReadOnly
|QIODevice::Unbuffered
));
2792 void tst_QFile::openStandardStreams()
2794 // Using file descriptors
2797 in
.open(STDIN_FILENO
, QIODevice::ReadOnly
);
2798 QCOMPARE( in
.pos(), (qint64
)0 );
2799 QCOMPARE( in
.size(), (qint64
)0 );
2800 QVERIFY( in
.isSequential() );
2805 out
.open(STDOUT_FILENO
, QIODevice::WriteOnly
);
2806 QCOMPARE( out
.pos(), (qint64
)0 );
2807 QCOMPARE( out
.size(), (qint64
)0 );
2808 QVERIFY( out
.isSequential() );
2813 err
.open(STDERR_FILENO
, QIODevice::WriteOnly
);
2814 QCOMPARE( err
.pos(), (qint64
)0 );
2815 QCOMPARE( err
.size(), (qint64
)0 );
2816 QVERIFY( err
.isSequential() );
2822 in
.open(stdin
, QIODevice::ReadOnly
);
2823 QCOMPARE( in
.pos(), (qint64
)0 );
2824 QCOMPARE( in
.size(), (qint64
)0 );
2825 QVERIFY( in
.isSequential() );
2830 out
.open(stdout
, QIODevice::WriteOnly
);
2831 QCOMPARE( out
.pos(), (qint64
)0 );
2832 QCOMPARE( out
.size(), (qint64
)0 );
2833 QVERIFY( out
.isSequential() );
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
);
2856 QTEST_MAIN(tst_QFile
)
2857 #include "tst_qfile.moc"