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();
215 // disabled this test for the moment... it hangs
216 void invalidFile_data();
220 enum FileType
{ OpenQFile
, OpenFd
, OpenStream
};
222 bool openFd(QFile
&file
, QIODevice::OpenMode mode
)
224 int fdMode
= QT_OPEN_LARGEFILE
| QT_OPEN_BINARY
;
226 // File will be truncated if in Write mode.
227 if (mode
& QIODevice::WriteOnly
)
228 fdMode
|= QT_OPEN_WRONLY
| QT_OPEN_TRUNC
;
229 if (mode
& QIODevice::ReadOnly
)
230 fdMode
|= QT_OPEN_RDONLY
;
232 fd_
= QT_OPEN(qPrintable(file
.fileName()), fdMode
);
234 return (-1 != fd_
) && file
.open(fd_
, mode
);
237 bool openStream(QFile
&file
, QIODevice::OpenMode mode
)
239 char const *streamMode
= "";
241 // File will be truncated if in Write mode.
242 if (mode
& QIODevice::WriteOnly
)
244 else if (mode
& QIODevice::ReadOnly
)
247 stream_
= QT_FOPEN(qPrintable(file
.fileName()), streamMode
);
249 return stream_
&& file
.open(stream_
, mode
);
252 bool openFile(QFile
&file
, QIODevice::OpenMode mode
, FileType type
= OpenQFile
)
254 if (mode
& QIODevice::WriteOnly
&& !file
.exists())
256 // Make sure the file exists
257 QFile
createFile(file
.fileName());
258 if (!createFile
.open(QIODevice::ReadWrite
))
262 // Note: openFd and openStream will truncate the file if write mode.
266 return file
.open(mode
);
269 return openFd(file
, mode
);
272 return openStream(file
, mode
);
278 void closeFile(QFile
&file
)
295 tst_QFile::tst_QFile()
299 tst_QFile::~tst_QFile()
304 void tst_QFile::init()
306 // TODO: Add initialization code here.
307 // This will be executed immediately before each test is run.
312 void tst_QFile::cleanup()
314 // TODO: Add cleanup code here.
315 // This will be executed immediately after each test is run.
317 // for copyFallback()
318 if (QFile::exists("file-copy-destination.txt")) {
319 QFile::setPermissions("file-copy-destination.txt",
320 QFile::ReadOwner
| QFile::WriteOwner
);
321 QFile::remove("file-copy-destination.txt");
324 // for renameFallback()
325 QFile::remove("file-rename-destination.txt");
327 // for copyAfterFail()
328 QFile::remove("file-to-be-copied.txt");
329 QFile::remove("existing-file.txt");
330 QFile::remove("copied-file-1.txt");
331 QFile::remove("copied-file-2.txt");
333 // for renameMultiple()
334 QFile::remove("file-to-be-renamed.txt");
335 QFile::remove("existing-file.txt");
336 QFile::remove("file-renamed-once.txt");
337 QFile::remove("file-renamed-twice.txt");
345 void tst_QFile::initTestCase()
347 QFile::remove("noreadfile");
349 // create a file and make it read-only
350 QFile
file("readonlyfile");
351 file
.open(QFile::WriteOnly
);
354 file
.setPermissions(QFile::ReadOwner
);
356 // create another file and make it not readable
357 file
.setFileName("noreadfile");
358 file
.open(QFile::WriteOnly
);
361 file
.setPermissions(0);
364 void tst_QFile::cleanupTestCase()
366 // clean up the files we created
367 QFile::remove("readonlyfile");
368 QFile::remove("noreadfile");
369 QFile::remove("myLink.lnk");
370 QFile::remove("appendme.txt");
371 QFile::remove("createme.txt");
372 QFile::remove("file.txt");
373 QFile::remove("genfile.txt");
374 QFile::remove("seekToPos.txt");
375 QFile::remove("setsizeseek.txt");
376 QFile::remove("stdfile.txt");
377 QFile::remove("textfile.txt");
378 QFile::remove("truncate.txt");
379 QFile::remove("winfile.txt");
380 QFile::remove("writeonlyfile");
381 QFile::remove("largeblockfile.txt");
382 QFile::remove("tst_qfile_copy.cpp");
383 QFile::remove("nullinline.txt");
384 QFile::remove("myLink2.lnk");
385 QFile::remove("resources");
386 QFile::remove("qfile_map_testfile");
389 //------------------------------------------
390 // The 'testfile' is currently just a
391 // testfile. The path of this file, the
392 // attributes and the contents itself
393 // will be changed as far as we have a
394 // proper way to handle files in the
395 // testing enviroment.
396 //------------------------------------------
398 void tst_QFile::exists()
400 QFile
f( SRCDIR
"testfile.txt" );
401 QCOMPARE( f
.exists(), (bool)TRUE
);
403 QFile
file("nobodyhassuchafile");
405 QVERIFY(!file
.exists());
407 QFile
file2("nobodyhassuchafile");
408 QVERIFY(file2
.open(QIODevice::WriteOnly
));
411 QVERIFY(file
.exists());
413 QVERIFY(file
.open(QIODevice::WriteOnly
));
415 QVERIFY(file
.exists());
418 QVERIFY(!file
.exists());
420 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
421 QFile
unc("//" + QtNetworkSettings::winServerName() + "/testshare/readme.txt");
422 QVERIFY(unc
.exists());
426 void tst_QFile::open_data()
428 QTest::addColumn
<QString
>("filename");
429 QTest::addColumn
<int>("mode");
430 QTest::addColumn
<bool>("ok");
431 QTest::addColumn
<QFile::FileError
>("status");
434 static const QString
denied("Operation not permitted");
436 static const QString
denied("Permission denied");
438 QTest::newRow( "exist_readOnly" )
439 << QString(SRCDIR
"testfile.txt") << int(QIODevice::ReadOnly
)
440 << (bool)TRUE
<< QFile::NoError
;
442 QTest::newRow( "exist_writeOnly" )
443 << QString("readonlyfile")
444 << int(QIODevice::WriteOnly
)
448 QTest::newRow( "exist_append" )
449 << QString("readonlyfile") << int(QIODevice::Append
)
450 << (bool)FALSE
<< QFile::OpenError
;
452 QTest::newRow( "nonexist_readOnly" )
453 << QString("nonExist.txt") << int(QIODevice::ReadOnly
)
454 << (bool)FALSE
<< QFile::OpenError
;
456 QTest::newRow("emptyfile")
458 << int(QIODevice::ReadOnly
)
462 QTest::newRow("nullfile") << QString() << int(QIODevice::ReadOnly
) << (bool)FALSE
465 QTest::newRow("two-dots") << QString(SRCDIR
"two.dots.file") << int(QIODevice::ReadOnly
) << (bool)TRUE
468 QTest::newRow("readonlyfile") << QString("readonlyfile") << int(QIODevice::WriteOnly
)
469 << (bool)FALSE
<< QFile::OpenError
;
470 QTest::newRow("noreadfile") << QString("noreadfile") << int(QIODevice::ReadOnly
)
471 << (bool)FALSE
<< QFile::OpenError
;
472 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
473 QTest::newRow("//./PhysicalDrive0") << QString("//./PhysicalDrive0") << int(QIODevice::ReadOnly
)
474 << (bool)TRUE
<< QFile::NoError
;
475 QTest::newRow("uncFile") << "//" + QtNetworkSettings::winServerName() + "/testsharewritable/test.pri" << int(QIODevice::ReadOnly
)
476 << true << QFile::NoError
;
480 void tst_QFile::open()
482 QFETCH( QString
, filename
);
489 #if defined(Q_OS_SYMBIAN)
490 if (qstrcmp(QTest::currentDataTag(), "noreadfile") == 0)
491 QSKIP("Symbian does not support non-readable files", SkipSingle
);
492 #elif defined(Q_OS_UNIX)
494 // root and Chuck Norris don't care for file permissions. Skip.
495 QSKIP("Running this test as root doesn't make sense", SkipAll
);
498 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
499 QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort
);
501 if (filename
.isEmpty())
502 QTest::ignoreMessage(QtWarningMsg
, "QFSFileEngine::open: No file name specified");
504 QCOMPARE(f
.open( QIODevice::OpenMode(mode
) ), ok
);
506 QTEST( f
.error(), "status" );
509 void tst_QFile::openUnbuffered()
511 QFile
file(SRCDIR
"testfile.txt");
512 QVERIFY(file
.open(QIODevice::ReadOnly
| QIODevice::Unbuffered
));
514 QVERIFY(file
.seek(1));
515 QCOMPARE(file
.pos(), qint64(1));
516 QVERIFY(file
.getChar(&c
));
517 QCOMPARE(file
.pos(), qint64(2));
519 QVERIFY(file
.seek(3));
520 QCOMPARE(file
.pos(), qint64(3));
521 QVERIFY(file
.getChar(&d
));
522 QCOMPARE(file
.pos(), qint64(4));
523 QVERIFY(file
.seek(1));
524 QCOMPARE(file
.pos(), qint64(1));
526 QVERIFY(file
.getChar(&c2
));
527 QCOMPARE(file
.pos(), qint64(2));
528 QVERIFY(file
.seek(3));
529 QCOMPARE(file
.pos(), qint64(3));
531 QVERIFY(file
.getChar(&d2
));
532 QCOMPARE(file
.pos(), qint64(4));
539 void tst_QFile::size_data()
541 QTest::addColumn
<QString
>("filename");
542 QTest::addColumn
<qint64
>("size");
544 QTest::newRow( "exist01" ) << QString(SRCDIR
"testfile.txt") << (qint64
)245;
545 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
546 // Only test UNC on Windows./
547 QTest::newRow("unc") << "//" + QString(QtNetworkSettings::winServerName() + "/testsharewritable/test.pri") << (qint64
)34;
551 void tst_QFile::size()
553 QFETCH( QString
, filename
);
554 QFETCH( qint64
, size
);
558 QCOMPARE( f
.size(), size
);
560 QVERIFY( f
.open(QIODevice::ReadOnly
) );
561 QCOMPARE( f
.size(), size
);
566 int fd
= QT_OPEN(filename
.toLocal8Bit().constData(), QT_OPEN_RDONLY
);
568 QVERIFY( f
.open(fd
, QIODevice::ReadOnly
) );
569 QCOMPARE( f
.size(), size
);
577 FILE* stream
= QT_FOPEN(filename
.toLocal8Bit().constData(), "rb");
579 QVERIFY( f
.open(stream
, QIODevice::ReadOnly
) );
580 QCOMPARE( f
.size(), size
);
587 void tst_QFile::sizeNoExist()
589 QFile
file("nonexist01");
590 QVERIFY( !file
.exists() );
591 QCOMPARE( file
.size(), (qint64
)0 );
592 QVERIFY( !file
.open(QIODevice::ReadOnly
) );
595 void tst_QFile::seek()
597 QFile::remove("newfile.txt");
598 QFile
file("newfile.txt");
599 file
.open(QIODevice::WriteOnly
);
600 QCOMPARE(file
.size(), qint64(0));
601 QCOMPARE(file
.pos(), qint64(0));
602 QVERIFY(file
.seek(10));
603 QCOMPARE(file
.pos(), qint64(10));
604 QCOMPARE(file
.size(), qint64(0));
605 QFile::remove("newfile.txt");
608 void tst_QFile::setSize()
610 DEPENDS_ON( "size" );
612 if ( QFile::exists( "createme.txt" ) )
613 QFile::remove( "createme.txt" );
614 QVERIFY( !QFile::exists( "createme.txt" ) );
616 QFile
f("createme.txt");
617 QVERIFY(f
.open(QIODevice::Truncate
| QIODevice::ReadWrite
));
625 QCOMPARE(f
.size(), (qlonglong
)1);
626 bool ok
= f
.resize(99);
628 QCOMPARE(f
.size(), (qlonglong
)99);
635 QVERIFY(f
.resize(1));
636 QCOMPARE(f
.size(), (qlonglong
)1);
645 QCOMPARE(f
.size(), (qlonglong
)1);
646 QVERIFY(f
.resize(100));
647 QCOMPARE(f
.size(), (qlonglong
)100);
648 QVERIFY(f
.resize(50));
649 QCOMPARE(f
.size(), (qlonglong
)50);
652 void tst_QFile::setSizeSeek()
654 QFile::remove("setsizeseek.txt");
655 QFile
f("setsizeseek.txt");
656 QVERIFY(f
.open(QFile::WriteOnly
));
659 QCOMPARE(f
.pos(), qint64(4));
661 QCOMPARE(f
.pos(), qint64(2));
663 QCOMPARE(f
.pos(), qint64(2));
665 QCOMPARE(f
.pos(), qint64(0));
667 QCOMPARE(f
.pos(), qint64(0));
670 QCOMPARE(f
.pos(), qint64(3));
672 QCOMPARE(f
.pos(), qint64(2));
675 void tst_QFile::atEnd()
677 QFile
f( SRCDIR
"testfile.txt" );
678 QVERIFY(f
.open( QIODevice::ReadOnly
));
683 bool end
= f
.atEnd();
685 QCOMPARE( end
, (bool)TRUE
);
688 void tst_QFile::readLine()
690 QFile
f( SRCDIR
"testfile.txt" );
691 QVERIFY(f
.open( QIODevice::ReadOnly
));
696 while ( (foo
=f
.readLine( p
, 128 )) > 0 ) {
699 QCOMPARE( p
[0], 'T' );
700 QCOMPARE( p
[3], 's' );
701 QCOMPARE( p
[11], 'i' );
708 void tst_QFile::readLine2()
710 QFile
f( SRCDIR
"testfile.txt" );
711 f
.open( QIODevice::ReadOnly
);
714 QCOMPARE(f
.readLine(p
, 60), qlonglong(59));
715 QCOMPARE(f
.readLine(p
, 60), qlonglong(59));
716 memset(p
, '@', sizeof(p
));
717 QCOMPARE(f
.readLine(p
, 60), qlonglong(59));
719 QCOMPARE(p
[57], '-');
720 QCOMPARE(p
[58], '\n');
721 QCOMPARE(p
[59], '\0');
722 QCOMPARE(p
[60], '@');
725 void tst_QFile::readLineNullInLine()
727 QFile::remove("nullinline.txt");
728 QFile
file("nullinline.txt");
729 QVERIFY(file
.open(QIODevice::ReadWrite
));
730 QVERIFY(file
.write("linewith\0null\nanotherline\0withnull\n\0\nnull\0", 42) > 0);
731 QVERIFY(file
.flush());
734 QCOMPARE(file
.readLine(), QByteArray("linewith\0null\n", 14));
735 QCOMPARE(file
.readLine(), QByteArray("anotherline\0withnull\n", 21));
736 QCOMPARE(file
.readLine(), QByteArray("\0\n", 2));
737 QCOMPARE(file
.readLine(), QByteArray("null\0", 5));
738 QCOMPARE(file
.readLine(), QByteArray());
741 void tst_QFile::readAllStdin()
743 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
744 QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll
);
746 #if defined(QT_NO_PROCESS)
747 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll
);
749 QByteArray
lotsOfData(1024, '@'); // 10 megs
752 process
.start("stdinprocess/stdinprocess all");
753 for (int i
= 0; i
< 5; ++i
) {
755 process
.write(lotsOfData
);
756 while (process
.bytesToWrite() > 0) {
757 QVERIFY(process
.waitForBytesWritten());
761 process
.closeWriteChannel();
762 process
.waitForFinished();
763 QCOMPARE(process
.readAll().size(), lotsOfData
.size() * 5);
767 void tst_QFile::readLineStdin()
769 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
770 QSKIP("Currently no stdin/out supported for Windows CE or Symbian", SkipAll
);
772 #if defined(QT_NO_PROCESS)
773 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll
);
776 QByteArray
lotsOfData(1024, '@'); // 10 megs
777 for (int i
= 0; i
< lotsOfData
.size(); ++i
) {
779 lotsOfData
[i
] = '\n';
781 lotsOfData
[i
] = char('0' + i
% 32);
784 for (int i
= 0; i
< 2; ++i
) {
786 process
.start(QString("stdinprocess/stdinprocess line %1").arg(i
), QIODevice::Text
| QIODevice::ReadWrite
);
787 for (int i
= 0; i
< 5; ++i
) {
789 process
.write(lotsOfData
);
790 while (process
.bytesToWrite() > 0) {
791 QVERIFY(process
.waitForBytesWritten());
795 process
.closeWriteChannel();
796 QVERIFY(process
.waitForFinished(5000));
798 QByteArray array
= process
.readAll();
799 QCOMPARE(array
.size(), lotsOfData
.size() * 5);
800 for (int i
= 0; i
< array
.size(); ++i
) {
802 QCOMPARE(char(array
[i
]), '\n');
804 QCOMPARE(char(array
[i
]), char('0' + i
% 32));
810 void tst_QFile::readLineStdin_lineByLine()
812 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
813 QSKIP("Currently no stdin/out supported for Windows CE", SkipAll
);
815 #if defined(QT_NO_PROCESS)
816 QSKIP("Qt was compiled with QT_NO_PROCESS", SkipAll
);
818 for (int i
= 0; i
< 2; ++i
) {
820 process
.start(QString("stdinprocess/stdinprocess line %1").arg(i
), QIODevice::Text
| QIODevice::ReadWrite
);
821 QVERIFY(process
.waitForStarted());
823 for (int j
= 0; j
< 3; ++j
) {
824 QByteArray line
= "line " + QByteArray::number(j
) + "\n";
825 QCOMPARE(process
.write(line
), qint64(line
.size()));
826 QVERIFY(process
.waitForBytesWritten(2000));
827 if (process
.bytesAvailable() == 0)
828 QVERIFY(process
.waitForReadyRead(2000));
829 QCOMPARE(process
.readAll(), line
);
832 process
.closeWriteChannel();
833 QVERIFY(process
.waitForFinished(5000));
838 void tst_QFile::text()
840 // dosfile.txt is a binary CRLF file
841 QFile
file(SRCDIR
"dosfile.txt");
842 QVERIFY(file
.open(QFile::Text
| QFile::ReadOnly
));
843 QCOMPARE(file
.readLine(),
844 QByteArray("/dev/system/root / reiserfs acl,user_xattr 1 1\n"));
845 QCOMPARE(file
.readLine(),
846 QByteArray("/dev/sda1 /boot ext3 acl,user_xattr 1 2\n"));
847 file
.ungetChar('\n');
849 QCOMPARE(file
.readLine().constData(), QByteArray("2\n").constData());
852 void tst_QFile::missingEndOfLine()
854 QFile
file(SRCDIR
"noendofline.txt");
855 QVERIFY(file
.open(QFile::ReadOnly
));
858 while (!file
.atEnd()) {
866 void tst_QFile::readBlock()
868 QFile
f( SRCDIR
"testfile.txt" );
869 f
.open( QIODevice::ReadOnly
);
873 length
= f
.read( p
, 256 );
875 QCOMPARE( length
, 245 );
876 QCOMPARE( p
[59], 'D' );
877 QCOMPARE( p
[178], 'T' );
878 QCOMPARE( p
[199], 'l' );
881 void tst_QFile::getch()
883 QFile
f( SRCDIR
"testfile.txt" );
884 f
.open( QIODevice::ReadOnly
);
888 while (f
.getChar(&c
)) {
889 QCOMPARE(f
.pos(), qint64(i
+ 1));
898 void tst_QFile::ungetChar()
900 QFile
f(SRCDIR
"testfile.txt");
901 QVERIFY(f
.open(QIODevice::ReadOnly
));
903 QByteArray array
= f
.readLine();
904 QCOMPARE(array
.constData(), "----------------------------------------------------------\n");
907 array
= f
.readLine();
908 QCOMPARE(array
.constData(), "\n");
914 array
= f
.readLine();
915 QCOMPARE(array
.constData(), "--\n");
917 QFile::remove("genfile.txt");
918 QFile
out("genfile.txt");
919 QVERIFY(out
.open(QIODevice::ReadWrite
));
922 QCOMPARE(out
.readAll().constData(), "123");
926 QCOMPARE(out
.readAll().constData(), "124");
931 QCOMPARE(out
.read(buf
, sizeof(buf
)), qint64(3));
932 QCOMPARE(buf
[0], '1');
933 QCOMPARE(buf
[1], '2');
934 QCOMPARE(buf
[2], '4');
937 void tst_QFile::invalidFile_data()
939 QTest::addColumn
<QString
>("fileName");
940 #if !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN)
941 QTest::newRow( "x11" ) << QString( "qwe//" );
943 QTest::newRow( "colon1" ) << QString( "fail:invalid" );
944 QTest::newRow( "colon2" ) << QString( "f:ail:invalid" );
945 QTest::newRow( "colon3" ) << QString( ":failinvalid" );
946 QTest::newRow( "forwardslash" ) << QString( "fail/invalid" );
947 QTest::newRow( "asterisk" ) << QString( "fail*invalid" );
948 QTest::newRow( "questionmark" ) << QString( "fail?invalid" );
949 QTest::newRow( "quote" ) << QString( "fail\"invalid" );
950 QTest::newRow( "lt" ) << QString( "fail<invalid" );
951 QTest::newRow( "gt" ) << QString( "fail>invalid" );
952 QTest::newRow( "pipe" ) << QString( "fail|invalid" );
956 void tst_QFile::invalidFile()
958 QFETCH( QString
, fileName
);
960 QVERIFY( !f
.open( QIODevice::ReadWrite
) );
963 void tst_QFile::createFile()
965 if ( QFile::exists( "createme.txt" ) )
966 QFile::remove( "createme.txt" );
967 QVERIFY( !QFile::exists( "createme.txt" ) );
969 QFile
f( "createme.txt" );
970 QVERIFY( f
.open( QIODevice::WriteOnly
) );
972 QVERIFY( QFile::exists( "createme.txt" ) );
975 void tst_QFile::append()
977 const QString
name("appendme.txt");
978 if (QFile::exists(name
))
980 QVERIFY(!QFile::exists(name
));
983 QVERIFY(f
.open(QIODevice::WriteOnly
| QIODevice::Truncate
));
987 QVERIFY(f
.open(QIODevice::Append
));
988 QVERIFY(f
.pos() == 1);
991 QCOMPARE(int(f
.size()), 2);
994 void tst_QFile::permissions_data()
996 QTest::addColumn
<QString
>("file");
997 QTest::addColumn
<uint
>("perms");
998 QTest::addColumn
<bool>("expected");
1000 QTest::newRow("data0") << QCoreApplication::instance()->applicationFilePath() << uint(QFile::ExeUser
) << true;
1001 QTest::newRow("data1") << SRCDIR
"tst_qfile.cpp" << uint(QFile::ReadUser
) << true;
1002 // QTest::newRow("data2") << "tst_qfile.cpp" << int(QFile::WriteUser) << false;
1003 QTest::newRow("resource1") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ReadUser
) << true;
1004 QTest::newRow("resource2") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::WriteUser
) << false;
1005 QTest::newRow("resource3") << ":/tst_qfileinfo/resources/file1.ext1" << uint(QFile::ExeUser
) << false;
1008 void tst_QFile::permissions()
1010 #if defined(Q_OS_SYMBIAN)
1011 if (qstrcmp(QTest::currentDataTag(), "data0") == 0)
1012 QSKIP("Symbian does not have execution permissions", SkipSingle
);
1014 QFETCH(QString
, file
);
1015 QFETCH(uint
, perms
);
1016 QFETCH(bool, expected
);
1018 QCOMPARE(((f
.permissions() & perms
) == QFile::Permissions(perms
)), expected
);
1021 void tst_QFile::setPermissions()
1023 DEPENDS_ON( "permissions" ); //if that doesn't work...
1025 if ( QFile::exists( "createme.txt" ) )
1026 QFile::remove( "createme.txt" );
1027 QVERIFY( !QFile::exists( "createme.txt" ) );
1029 QFile
f("createme.txt");
1030 QVERIFY(f
.open(QIODevice::WriteOnly
| QIODevice::Truncate
));
1034 QFile::Permissions
perms(QFile::WriteUser
| QFile::ReadUser
);
1035 QVERIFY(f
.setPermissions(perms
));
1036 QVERIFY((f
.permissions() & perms
) == perms
);
1040 void tst_QFile::copy()
1042 QFile::setPermissions("tst_qfile_copy.cpp", QFile::WriteUser
);
1043 QFile::remove("tst_qfile_copy.cpp");
1044 QFile::remove("test2");
1045 QVERIFY(QFile::copy(SRCDIR
"tst_qfile.cpp", "tst_qfile_copy.cpp"));
1046 QFile
in1(SRCDIR
"tst_qfile.cpp"), in2("tst_qfile_copy.cpp");
1047 QVERIFY(in1
.open(QFile::ReadOnly
));
1048 QVERIFY(in2
.open(QFile::ReadOnly
));
1049 QByteArray data1
= in1
.readAll(), data2
= in2
.readAll();
1050 QCOMPARE(data1
, data2
);
1051 QFile::remove( "main_copy.cpp" );
1053 QFile::copy(QDir::currentPath(), QDir::currentPath() + QLatin1String("/test2"));
1056 void tst_QFile::copyAfterFail()
1058 QFile
file1("file-to-be-copied.txt");
1059 QFile
file2("existing-file.txt");
1061 QVERIFY(file1
.open(QIODevice::ReadWrite
) && "(test-precondition)");
1062 QVERIFY(file2
.open(QIODevice::ReadWrite
) && "(test-precondition)");
1064 QVERIFY(!QFile::exists("copied-file-1.txt") && "(test-precondition)");
1065 QVERIFY(!QFile::exists("copied-file-2.txt") && "(test-precondition)");
1067 QVERIFY(!file1
.copy("existing-file.txt"));
1068 QCOMPARE(file1
.error(), QFile::CopyError
);
1070 QVERIFY(file1
.copy("copied-file-1.txt"));
1071 QVERIFY(!file1
.isOpen());
1072 QCOMPARE(file1
.error(), QFile::NoError
);
1074 QVERIFY(!file1
.copy("existing-file.txt"));
1075 QCOMPARE(file1
.error(), QFile::CopyError
);
1077 QVERIFY(file1
.copy("copied-file-2.txt"));
1078 QVERIFY(!file1
.isOpen());
1079 QCOMPARE(file1
.error(), QFile::NoError
);
1081 QVERIFY(QFile::exists("copied-file-1.txt"));
1082 QVERIFY(QFile::exists("copied-file-2.txt"));
1084 QVERIFY(QFile::remove("file-to-be-copied.txt") && "(test-cleanup)");
1085 QVERIFY(QFile::remove("existing-file.txt") && "(test-cleanup)");
1086 QVERIFY(QFile::remove("copied-file-1.txt") && "(test-cleanup)");
1087 QVERIFY(QFile::remove("copied-file-2.txt") && "(test-cleanup)");
1090 void tst_QFile::copyRemovesTemporaryFile() const
1092 const QString
newName(QLatin1String("copyRemovesTemporaryFile"));
1093 QVERIFY(QFile::copy(SRCDIR
"forCopying.txt", newName
));
1095 QVERIFY(!QFile::exists(QLatin1String( SRCDIR
"qt_temp.XXXXXX")));
1096 QVERIFY(QFile::remove(newName
));
1099 void tst_QFile::copyShouldntOverwrite()
1101 // Copy should not overwrite existing files.
1102 QFile::remove("tst_qfile.cpy");
1103 QFile
file(SRCDIR
"tst_qfile.cpp");
1104 QVERIFY(file
.copy("tst_qfile.cpy"));
1105 #if defined(Q_OS_SYMBIAN)
1106 bool ok
= QFile::setPermissions("tst_qfile.cpy", QFile::WriteUser
);
1108 bool ok
= QFile::setPermissions("tst_qfile.cpy", QFile::WriteOther
);
1111 QVERIFY(!file
.copy("tst_qfile.cpy"));
1112 QFile::remove("tst_qfile.cpy");
1115 void tst_QFile::copyFallback()
1117 // Using a resource file to trigger QFile::copy's fallback handling
1118 QFile
file(":/copy-fallback.qrc");
1119 QFile::remove("file-copy-destination.txt");
1121 QVERIFY2(file
.exists(), "test precondition");
1122 QVERIFY2(!QFile::exists("file-copy-destination.txt"), "test precondition");
1124 // Fallback copy of closed file.
1125 QVERIFY(file
.copy("file-copy-destination.txt"));
1126 QVERIFY(QFile::exists("file-copy-destination.txt"));
1127 QVERIFY(!file
.isOpen());
1129 // Need to reset permissions on Windows to be able to delete
1130 QVERIFY(QFile::setPermissions("file-copy-destination.txt",
1131 QFile::ReadOwner
| QFile::WriteOwner
));
1132 QVERIFY(QFile::remove("file-copy-destination.txt"));
1134 // Fallback copy of open file.
1135 QVERIFY(file
.open(QIODevice::ReadOnly
));
1136 QVERIFY(file
.copy("file-copy-destination.txt"));
1137 QVERIFY(QFile::exists("file-copy-destination.txt"));
1138 QVERIFY(!file
.isOpen());
1140 QFile::remove("file-copy-destination.txt");
1144 #include <objbase.h>
1148 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1149 static QString
getWorkingDirectoryForLink(const QString
&linkFileName
)
1151 bool neededCoInit
= false;
1155 HRESULT hres
= CoCreateInstance(CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
, IID_IShellLink
, (void **)&psl
);
1156 if (hres
== CO_E_NOTINITIALIZED
) { // COM was not initialized
1157 neededCoInit
= true;
1159 hres
= CoCreateInstance(CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
, IID_IShellLink
, (void **)&psl
);
1162 if (SUCCEEDED(hres
)) { // Get pointer to the IPersistFile interface.
1164 hres
= psl
->QueryInterface(IID_IPersistFile
, (LPVOID
*)&ppf
);
1165 if (SUCCEEDED(hres
)) {
1166 hres
= ppf
->Load((LPOLESTR
)linkFileName
.utf16(), STGM_READ
);
1167 //The original path of the link is retrieved. If the file/folder
1168 //was moved, the return value still have the old path.
1169 if(SUCCEEDED(hres
)) {
1170 wchar_t szGotPath
[MAX_PATH
];
1171 if (psl
->GetWorkingDirectory(szGotPath
, MAX_PATH
) == NOERROR
)
1172 ret
= QString::fromWCharArray(szGotPath
);
1187 void tst_QFile::link()
1189 QFile::remove("myLink.lnk");
1190 QFileInfo
info1("tst_qfile.cpp");
1191 QVERIFY(QFile::link("tst_qfile.cpp", "myLink.lnk"));
1192 QFileInfo
info2("myLink.lnk");
1193 QVERIFY(info2
.isSymLink());
1194 QCOMPARE(info2
.symLinkTarget(), info1
.absoluteFilePath());
1196 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1197 QString wd
= getWorkingDirectoryForLink(info2
.absoluteFilePath());
1198 QCOMPARE(QDir::fromNativeSeparators(wd
), info1
.absolutePath());
1200 QVERIFY(QFile::remove(info2
.absoluteFilePath()));
1203 void tst_QFile::linkToDir()
1205 #if defined(Q_OS_SYMBIAN)
1206 QSKIP("Symbian does not support linking to directories", SkipAll
);
1208 QFile::remove("myLinkToDir.lnk");
1211 QFileInfo
info1("myDir");
1212 QVERIFY(QFile::link("myDir", "myLinkToDir.lnk"));
1213 QFileInfo
info2("myLinkToDir.lnk");
1214 #if !(defined Q_OS_HPUX && defined(__ia64))
1215 // absurd HP-UX filesystem bug on gravlaks - checking if a symlink
1216 // resolves or not alters the file system to make the broken symlink
1218 QVERIFY(info2
.isSymLink());
1220 QCOMPARE(info2
.symLinkTarget(), info1
.absoluteFilePath());
1221 QVERIFY(QFile::remove(info2
.absoluteFilePath()));
1222 QFile::remove("myLinkToDir.lnk");
1226 void tst_QFile::absolutePathLinkToRelativePath()
1228 QFile::remove("myDir/test.txt");
1229 QFile::remove("myDir/myLink.lnk");
1232 QFile("myDir/test.txt").open(QFile::WriteOnly
);
1235 QVERIFY(QFile::link("test.txt", "myDir/myLink.lnk"));
1237 QVERIFY(QFile::link("myDir/test.txt", "myDir/myLink.lnk"));
1239 QEXPECT_FAIL("", "Symlinking using relative paths is currently different on Windows and Unix/Symbian", Continue
);
1240 QCOMPARE(QFileInfo(QFile(QFileInfo("myDir/myLink.lnk").absoluteFilePath()).symLinkTarget()).absoluteFilePath(),
1241 QFileInfo("myDir/test.txt").absoluteFilePath());
1243 QFile::remove("myDir/test.txt");
1244 QFile::remove("myDir/myLink.lnk");
1248 void tst_QFile::readBrokenLink()
1250 QFile::remove("myLink2.lnk");
1251 QFileInfo
info1("file12");
1252 #if defined(Q_OS_SYMBIAN)
1253 // In Symbian can't link to nonexisting file directly, so create the file temporarily
1254 QFile
tempFile("file12");
1255 tempFile
.open(QIODevice::WriteOnly
);
1256 tempFile
.link("myLink2.lnk");
1259 QVERIFY(QFile::link("file12", "myLink2.lnk"));
1261 QFileInfo
info2("myLink2.lnk");
1262 QVERIFY(info2
.isSymLink());
1263 QCOMPARE(info2
.symLinkTarget(), info1
.absoluteFilePath());
1264 QVERIFY(QFile::remove(info2
.absoluteFilePath()));
1266 #if !defined(Q_OS_SYMBIAN)
1267 QVERIFY(QFile::link("ole/..", "myLink2.lnk"));
1268 QCOMPARE(QFileInfo("myLink2.lnk").symLinkTarget(), QDir::currentPath());
1272 void tst_QFile::readTextFile_data()
1274 QTest::addColumn
<QByteArray
>("in");
1275 QTest::addColumn
<QByteArray
>("out");
1277 QTest::newRow("empty") << QByteArray() << QByteArray();
1278 QTest::newRow("a") << QByteArray("a") << QByteArray("a");
1279 QTest::newRow("a\\rb") << QByteArray("a\rb") << QByteArray("ab");
1280 QTest::newRow("\\n") << QByteArray("\n") << QByteArray("\n");
1281 QTest::newRow("\\r\\n") << QByteArray("\r\n") << QByteArray("\n");
1282 QTest::newRow("\\r") << QByteArray("\r") << QByteArray();
1283 QTest::newRow("twolines") << QByteArray("Hello\r\nWorld\r\n") << QByteArray("Hello\nWorld\n");
1284 QTest::newRow("twolines no endline") << QByteArray("Hello\r\nWorld") << QByteArray("Hello\nWorld");
1287 void tst_QFile::readTextFile()
1289 QFETCH(QByteArray
, in
);
1290 QFETCH(QByteArray
, out
);
1292 QFile
winfile("winfile.txt");
1293 QVERIFY(winfile
.open(QFile::WriteOnly
| QFile::Truncate
));
1297 QVERIFY(winfile
.open(QFile::ReadOnly
));
1298 QCOMPARE(winfile
.readAll(), in
);
1301 QVERIFY(winfile
.open(QFile::ReadOnly
| QFile::Text
));
1302 QCOMPARE(winfile
.readAll(), out
);
1305 void tst_QFile::readTextFile2()
1308 QFile
file(SRCDIR
"testlog.txt");
1309 QVERIFY(file
.open(QIODevice::ReadOnly
));
1314 QFile
file(SRCDIR
"testlog.txt");
1315 QVERIFY(file
.open(QIODevice::ReadOnly
| QIODevice::Text
));
1320 void tst_QFile::writeTextFile_data()
1322 QTest::addColumn
<QByteArray
>("in");
1324 QTest::newRow("empty") << QByteArray();
1325 QTest::newRow("a") << QByteArray("a");
1326 QTest::newRow("a\\rb") << QByteArray("a\rb");
1327 QTest::newRow("\\n") << QByteArray("\n");
1328 QTest::newRow("\\r\\n") << QByteArray("\r\n");
1329 QTest::newRow("\\r") << QByteArray("\r");
1330 QTest::newRow("twolines crlf") << QByteArray("Hello\r\nWorld\r\n");
1331 QTest::newRow("twolines crlf no endline") << QByteArray("Hello\r\nWorld");
1332 QTest::newRow("twolines lf") << QByteArray("Hello\nWorld\n");
1333 QTest::newRow("twolines lf no endline") << QByteArray("Hello\nWorld");
1334 QTest::newRow("mixed") << QByteArray("this\nis\r\na\nmixed\r\nfile\n");
1337 void tst_QFile::writeTextFile()
1339 QFETCH(QByteArray
, in
);
1341 QFile
file("textfile.txt");
1342 QVERIFY(file
.open(QFile::WriteOnly
| QFile::Truncate
| QFile::Text
));
1343 QByteArray out
= in
;
1345 out
.replace('\n', "\r\n");
1347 QCOMPARE(file
.write(in
), qlonglong(in
.size()));
1350 file
.open(QFile::ReadOnly
);
1351 QCOMPARE(file
.readAll(), out
);
1354 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1355 void tst_QFile::largeUncFileSupport()
1357 qint64 size
= Q_INT64_C(8589934592);
1358 qint64 dataOffset
= Q_INT64_C(8589914592);
1359 QByteArray
knownData("LargeFile content at offset 8589914592");
1360 QString
largeFile("//" + QtNetworkSettings::winServerName() + "/testsharelargefile/file.bin");
1363 // 1) Native file handling.
1364 QFile
file(largeFile
);
1365 QCOMPARE(file
.size(), size
);
1366 QVERIFY(file
.open(QIODevice::ReadOnly
));
1367 QCOMPARE(file
.size(), size
);
1368 QVERIFY(file
.seek(dataOffset
));
1369 QCOMPARE(file
.read(knownData
.size()), knownData
);
1372 // 2) stdlib file handling.
1373 #if _MSC_VER <= 1310
1374 QSKIP("platform SDK for MSVC 2003 does not support large files", SkipAll
);
1377 FILE *fh
= fopen(QFile::encodeName(largeFile
).data(), "rb");
1378 QVERIFY(file
.open(fh
, QIODevice::ReadOnly
));
1379 QCOMPARE(file
.size(), size
);
1380 QVERIFY(file
.seek(dataOffset
));
1381 QCOMPARE(file
.read(knownData
.size()), knownData
);
1385 // 3) stdio file handling.
1387 FILE *fh
= fopen(QFile::encodeName(largeFile
).data(), "rb");
1388 int fd
= int(_fileno(fh
));
1389 QVERIFY(file
.open(fd
, QIODevice::ReadOnly
));
1390 QCOMPARE(file
.size(), size
);
1391 QVERIFY(file
.seek(dataOffset
));
1392 QCOMPARE(file
.read(knownData
.size()), knownData
);
1398 void tst_QFile::tailFile()
1400 QSKIP("File change notifications are so far unsupported.", SkipAll
);
1402 QFile
file("tail.txt");
1403 QVERIFY(file
.open(QFile::WriteOnly
| QFile::Append
));
1405 QFile
tailFile("tail.txt");
1406 QVERIFY(tailFile
.open(QFile::ReadOnly
));
1407 tailFile
.seek(file
.size());
1409 QSignalSpy
readSignal(&tailFile
, SIGNAL(readyRead()));
1413 QTestEventLoop::instance().enterLoop(5);
1415 QVERIFY(!QTestEventLoop::instance().timeout());
1416 QCOMPARE(readSignal
.count(), 1);
1419 void tst_QFile::flush()
1421 QString
fileName("stdfile.txt");
1423 QFile::remove(fileName
);
1426 QFile
file(fileName
);
1427 QVERIFY(file
.open(QFile::WriteOnly
));
1428 QCOMPARE(file
.write("abc", 3),qint64(3));
1432 QFile
file(fileName
);
1433 QVERIFY(file
.open(QFile::WriteOnly
| QFile::Append
));
1434 QCOMPARE(file
.pos(), qlonglong(3));
1435 QCOMPARE(file
.write("def", 3), qlonglong(3));
1436 QCOMPARE(file
.pos(), qlonglong(6));
1440 QFile
file("stdfile.txt");
1441 QVERIFY(file
.open(QFile::ReadOnly
));
1442 QCOMPARE(file
.readAll(), QByteArray("abcdef"));
1445 QFile::remove(fileName
);
1448 void tst_QFile::bufferedRead()
1450 QFile::remove("stdfile.txt");
1452 QFile
file("stdfile.txt");
1453 QVERIFY(file
.open(QFile::WriteOnly
));
1454 file
.write("abcdef");
1457 #if defined(Q_OS_WINCE)
1458 FILE *stdFile
= fopen((QCoreApplication::applicationDirPath() + "/stdfile.txt").toAscii() , "r");
1460 FILE *stdFile
= fopen("stdfile.txt", "r");
1464 QCOMPARE(int(fread(&c
, 1, 1, stdFile
)), 1);
1466 QCOMPARE(int(ftell(stdFile
)), 1);
1470 QVERIFY(file
.open(stdFile
, QFile::ReadOnly
));
1471 QCOMPARE(file
.pos(), qlonglong(1));
1472 QCOMPARE(file
.read(&c
, 1), qlonglong(1));
1474 QCOMPARE(file
.pos(), qlonglong(2));
1480 void tst_QFile::isSequential()
1482 #if defined (Q_OS_WIN) || defined(Q_OS_SYMBIAN)
1483 QSKIP("Unix only test.", SkipAll
);
1486 QFile
zero("/dev/null");
1487 QVERIFY(zero
.open(QFile::ReadOnly
));
1488 QVERIFY(zero
.isSequential());
1491 void tst_QFile::encodeName()
1493 QCOMPARE(QFile::encodeName(QString::null
), QByteArray());
1496 void tst_QFile::truncate()
1498 for (int i
= 0; i
< 2; ++i
) {
1499 QFile
file("truncate.txt");
1500 QVERIFY(file
.open(QFile::WriteOnly
));
1501 file
.write(QByteArray(200, '@'));
1504 QVERIFY(file
.open((i
? QFile::WriteOnly
: QFile::ReadWrite
) | QFile::Truncate
));
1505 file
.write(QByteArray(100, '$'));
1508 QVERIFY(file
.open(QFile::ReadOnly
));
1509 QCOMPARE(file
.readAll(), QByteArray(100, '$'));
1513 void tst_QFile::seekToPos()
1516 QFile
file("seekToPos.txt");
1517 QVERIFY(file
.open(QFile::WriteOnly
));
1518 file
.write("a\r\nb\r\nc\r\n");
1522 QFile
file("seekToPos.txt");
1523 QVERIFY(file
.open(QFile::ReadOnly
| QFile::Text
));
1526 QVERIFY(file
.getChar(&c
));
1529 QCOMPARE(file
.pos(), qint64(3));
1530 file
.seek(file
.pos());
1531 QCOMPARE(file
.pos(), qint64(3));
1534 file
.seek(file
.pos());
1535 QCOMPARE(file
.pos(), qint64(1));
1540 void tst_QFile::FILEReadWrite()
1542 // Tests modifing a file. First creates it then reads in 4 bytes and then overwrites these
1543 // 4 bytes with new values. At the end check to see the file contains the new values.
1545 QFile::remove("FILEReadWrite.txt");
1549 QFile
f("FILEReadWrite.txt");
1550 QVERIFY(f
.open(QFile::WriteOnly
));
1580 FILE *fp
= fopen(qPrintable(QCoreApplication::applicationDirPath() + "\\FILEReadWrite.txt"), "r+b");
1582 FILE *fp
= fopen("FILEReadWrite.txt", "r+b");
1586 QVERIFY(file
.open(fp
, QFile::ReadWrite
));
1587 QDataStream
sfile(&file
) ;
1589 qint8 var1
,var2
,var3
,var4
;
1590 while (!sfile
.atEnd())
1592 qint64 base
= file
.pos();
1594 QCOMPARE(file
.pos(), base
+ 0);
1596 QCOMPARE(file
.pos(), base
+ 1);
1597 file
.flush(); // flushing should not change the base
1598 QCOMPARE(file
.pos(), base
+ 1);
1600 QCOMPARE(file
.pos(), base
+ 2);
1602 QCOMPARE(file
.pos(), base
+ 3);
1604 QCOMPARE(file
.pos(), base
+ 4);
1605 file
.seek(file
.pos() - 4) ; // Move it back 4, for we are going to write new values based on old ones
1606 QCOMPARE(file
.pos(), base
+ 0);
1607 sfile
<< qint8(var1
+ 5);
1608 QCOMPARE(file
.pos(), base
+ 1);
1609 sfile
<< qint8(var2
+ 5);
1610 QCOMPARE(file
.pos(), base
+ 2);
1611 sfile
<< qint8(var3
+ 5);
1612 QCOMPARE(file
.pos(), base
+ 3);
1613 sfile
<< qint8(var4
+ 5);
1614 QCOMPARE(file
.pos(), base
+ 4);
1620 // check modified file
1622 QFile
f("FILEReadWrite.txt");
1623 QVERIFY(f
.open(QFile::ReadOnly
));
1627 QCOMPARE(c
, (qint8
)5);
1629 QCOMPARE(c
, (qint8
)6);
1631 QCOMPARE(c
, (qint8
)7);
1633 QCOMPARE(c
, (qint8
)8);
1635 QCOMPARE(c
, (qint8
)9);
1637 QCOMPARE(c
, (qint8
)10);
1639 QCOMPARE(c
, (qint8
)11);
1641 QCOMPARE(c
, (qint8
)12);
1643 QCOMPARE(c
, (qint8
)13);
1645 QCOMPARE(c
, (qint8
)14);
1647 QCOMPARE(c
, (qint8
)15);
1649 QCOMPARE(c
, (qint8
)16);
1653 QFile::remove("FILEReadWrite.txt");
1658 #include <qglobal.h>
1660 #define FILESIZE 0x10000000f
1661 void tst_QFile::largeFileSupport()
1664 QSKIP("Solaris does not support statfs", SkipAll);
1666 qlonglong sizeNeeded = 2147483647;
1669 qlonglong freespace = qlonglong(0);
1671 _ULARGE_INTEGER free;
1672 if (::GetDiskFreeSpaceEx((wchar_t*)QDir::currentPath().utf16(), &free, 0, 0))
1673 freespace = free.QuadPart;
1674 if (freespace != 0) {
1675 #elif defined(Q_OS_IRIX)
1677 if (statfs(QDir::currentPath().local8Bit(), &info, sizeof(struct statfs), 0) == 0) {
1678 freespace = qlonglong(info.f_bfree * info.f_bsize);
1681 if (statfs(const_cast<char *>(QDir::currentPath().toLocal8Bit().constData()), &info) == 0) {
1682 freespace = qlonglong(info.f_bavail * info.f_bsize);
1684 if (freespace > sizeNeeded) {
1685 QFile bigFile("bigfile");
1686 if (bigFile.open(QFile::ReadWrite)) {
1687 char c[BUFFSIZE] = {'a'};
1688 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
1689 qlonglong oldPos = bigFile.pos();
1690 QVERIFY(bigFile.resize(sizeNeeded));
1691 QCOMPARE(oldPos, bigFile.pos());
1692 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
1693 QVERIFY(bigFile.write(c, BUFFSIZE) == BUFFSIZE);
1696 if (bigFile.open(QFile::ReadOnly)) {
1697 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
1699 for (i=0; i<BUFFSIZE; i++)
1700 QCOMPARE(c[i], 'a');
1701 QVERIFY(bigFile.seek(sizeNeeded - BUFFSIZE));
1702 QVERIFY(bigFile.read(c, BUFFSIZE) == BUFFSIZE);
1703 for (i=0; i<BUFFSIZE; i++)
1704 QCOMPARE(c[i], 'a');
1706 QVERIFY(bigFile.remove());
1708 QVERIFY(bigFile.remove());
1709 QFAIL("Could not reopen file");
1712 QFAIL("Could not open file");
1715 QSKIP("Not enough space to run test", SkipSingle);
1718 QFAIL("Could not determin disk space");
1724 void tst_QFile::i18nFileName_data()
1726 QTest::addColumn
<QString
>("fileName");
1728 QTest::newRow( "01" ) << QString::fromUtf8("xxxxxxx.txt");
1731 void tst_QFile::i18nFileName()
1733 QFETCH(QString
, fileName
);
1734 if (QFile::exists(fileName
)) {
1735 QVERIFY(QFile::remove(fileName
));
1738 QFile
file(fileName
);
1739 QVERIFY(file
.open(QFile::WriteOnly
| QFile::Text
));
1740 QTextStream
ts(&file
);
1741 ts
.setCodec("UTF-8");
1742 ts
<< fileName
<< endl
;
1745 QFile
file(fileName
);
1746 QVERIFY(file
.open(QFile::ReadOnly
| QFile::Text
));
1747 QTextStream
ts(&file
);
1748 ts
.setCodec("UTF-8");
1749 QString line
= ts
.readLine();
1750 QCOMPARE(line
, fileName
);
1752 QVERIFY(QFile::remove(fileName
));
1756 void tst_QFile::longFileName_data()
1758 QTest::addColumn
<QString
>("fileName");
1760 QTest::newRow( "16 chars" ) << QString::fromLatin1("longFileName.txt");
1761 QTest::newRow( "52 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName.txt");
1762 QTest::newRow( "148 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1763 "longFileNamelongFileNamelongFileNamelongFileName"
1764 "longFileNamelongFileNamelongFileNamelongFileName.txt");
1765 QTest::newRow( "244 chars" ) << QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1766 "longFileNamelongFileNamelongFileNamelongFileName"
1767 "longFileNamelongFileNamelongFileNamelongFileName"
1768 "longFileNamelongFileNamelongFileNamelongFileName"
1769 "longFileNamelongFileNamelongFileNamelongFileName.txt");
1770 QTest::newRow( "244 chars to absolutepath" ) << QFileInfo(QString::fromLatin1("longFileNamelongFileNamelongFileNamelongFileName"
1771 "longFileNamelongFileNamelongFileNamelongFileName"
1772 "longFileNamelongFileNamelongFileNamelongFileName"
1773 "longFileNamelongFileNamelongFileNamelongFileName"
1774 "longFileNamelongFileNamelongFileNamelongFileName.txt")).absoluteFilePath();
1775 /* needs to be put on a windows 2000 > test machine
1776 QTest::newRow( "244 chars on UNC" ) << QString::fromLatin1("//arsia/D/troll/tmp/longFileNamelongFileNamelongFileNamelongFileName"
1777 "longFileNamelongFileNamelongFileNamelongFileName"
1778 "longFileNamelongFileNamelongFileNamelongFileName"
1779 "longFileNamelongFileNamelongFileNamelongFileName"
1780 "longFileNamelongFileNamelongFileNamelongFileName.txt");*/
1783 void tst_QFile::longFileName()
1785 QFETCH(QString
, fileName
);
1786 if (QFile::exists(fileName
)) {
1787 QVERIFY(QFile::remove(fileName
));
1790 QFile
file(fileName
);
1791 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
1792 QEXPECT_FAIL("244 chars", "Full pathname must be less than 260 chars", Abort
);
1793 QEXPECT_FAIL("244 chars to absolutepath", "Full pathname must be less than 260 chars", Abort
);
1795 QVERIFY(file
.open(QFile::WriteOnly
| QFile::Text
));
1796 QTextStream
ts(&file
);
1797 ts
<< fileName
<< endl
;
1800 QFile
file(fileName
);
1801 QVERIFY(file
.open(QFile::ReadOnly
| QFile::Text
));
1802 QTextStream
ts(&file
);
1803 QString line
= ts
.readLine();
1804 QCOMPARE(line
, fileName
);
1806 QString newName
= fileName
+ QLatin1String("1");
1808 QVERIFY(QFile::copy(fileName
, newName
));
1809 QFile
file(newName
);
1810 QVERIFY(file
.open(QFile::ReadOnly
| QFile::Text
));
1811 QTextStream
ts(&file
);
1812 QString line
= ts
.readLine();
1813 QCOMPARE(line
, fileName
);
1816 QVERIFY(QFile::remove(newName
));
1818 QVERIFY(QFile::rename(fileName
, newName
));
1819 QFile
file(newName
);
1820 QVERIFY(file
.open(QFile::ReadOnly
| QFile::Text
));
1821 QTextStream
ts(&file
);
1822 QString line
= ts
.readLine();
1823 QCOMPARE(line
, fileName
);
1825 QVERIFY(QFile::exists(newName
));
1826 QVERIFY(QFile::remove(newName
));
1829 class MyEngine
: public QAbstractFileEngine
1832 MyEngine(int n
) { number
= n
; }
1833 virtual ~MyEngine() {}
1835 void setFileName(const QString
&) {}
1836 bool open(int ) { return false; }
1837 bool close() { return false; }
1838 bool flush() { return false; }
1839 qint64
size() const { return 123 + number
; }
1840 qint64
at() const { return -1; }
1841 bool seek(qint64
) { return false; }
1842 bool isSequential() const { return false; }
1843 qint64
read(char *, qint64
) { return -1; }
1844 qint64
write(const char *, qint64
) { return -1; }
1845 bool remove() { return false; }
1846 bool copy(const QString
&) { return false; }
1847 bool rename(const QString
&) { return false; }
1848 bool link(const QString
&) { return false; }
1849 bool mkdir(const QString
&, bool) const { return false; }
1850 bool rmdir(const QString
&, bool) const { return false; }
1851 bool setSize(qint64
) { return false; }
1852 QStringList
entryList(QDir::Filters
, const QStringList
&) const { return QStringList(); }
1853 bool caseSensitive() const { return false; }
1854 bool isRelativePath() const { return false; }
1855 FileFlags
fileFlags(FileFlags
) const { return 0; }
1856 bool chmod(uint
) { return false; }
1857 QString
fileName(FileName
) const { return name
; }
1858 uint
ownerId(FileOwner
) const { return 0; }
1859 QString
owner(FileOwner
) const { return QString(); }
1860 QDateTime
fileTime(FileTime
) const { return QDateTime(); }
1867 class MyHandler
: public QAbstractFileEngineHandler
1870 inline QAbstractFileEngine
*create(const QString
&) const
1872 return new MyEngine(1);
1876 class MyHandler2
: public QAbstractFileEngineHandler
1879 inline QAbstractFileEngine
*create(const QString
&) const
1881 return new MyEngine(2);
1885 void tst_QFile::fileEngineHandler()
1887 // A file that does not exist has a size of 0.
1888 QFile::remove("ole.bull");
1889 QFile
file("ole.bull");
1890 QCOMPARE(file
.size(), qint64(0));
1892 // Instantiating our handler will enable the new engine.
1894 file
.setFileName("ole.bull");
1895 QCOMPARE(file
.size(), qint64(124));
1897 // A new, identical handler should take preference over the last one.
1898 MyHandler2 handler2
;
1899 file
.setFileName("ole.bull");
1900 QCOMPARE(file
.size(), qint64(125));
1904 class MyRecursiveHandler
: public QAbstractFileEngineHandler
1907 inline QAbstractFileEngine
*create(const QString
&fileName
) const
1909 if (fileName
.startsWith(":!")) {
1911 QString realFile
= SRCDIR
+ fileName
.mid(2);
1912 if (dir
.exists(realFile
))
1913 return new QFSFileEngine(realFile
);
1919 void tst_QFile::useQFileInAFileHandler()
1921 // This test should not dead-lock
1922 MyRecursiveHandler handler
;
1923 QFile
file(":!tst_qfile.cpp");
1924 QVERIFY(file
.exists());
1927 void tst_QFile::getCharFF()
1929 QFile
file("file.txt");
1930 file
.open(QFile::ReadWrite
);
1931 file
.write("\xff\xff\xff");
1936 QVERIFY(file
.getChar(&c
));
1937 QVERIFY(file
.getChar(&c
));
1938 QVERIFY(file
.getChar(&c
));
1941 void tst_QFile::remove_and_exists()
1943 QFile::remove("tull_i_grunn.txt");
1944 QFile
f("tull_i_grunn.txt");
1946 QVERIFY(!f
.exists());
1948 bool opened
= f
.open(QIODevice::WriteOnly
);
1951 f
.write(QString("testing that remove/exists work...").toLatin1());
1954 QVERIFY(f
.exists());
1957 QVERIFY(!f
.exists());
1960 void tst_QFile::removeOpenFile()
1963 // remove an opened, write-only file
1964 QFile::remove("remove_unclosed.txt");
1965 QFile
f("remove_unclosed.txt");
1967 QVERIFY(!f
.exists());
1968 bool opened
= f
.open(QIODevice::WriteOnly
);
1970 f
.write(QString("testing that remove closes the file first...").toLatin1());
1972 bool removed
= f
.remove(); // remove should both close and remove the file
1974 QVERIFY(!f
.isOpen());
1975 QVERIFY(!f
.exists());
1976 QVERIFY(f
.error() == QFile::NoError
);
1980 // remove an opened, read-only file
1981 QFile::remove("remove_unclosed.txt");
1983 // first, write a file that we can remove
1985 QFile
f("remove_unclosed.txt");
1986 QVERIFY(!f
.exists());
1987 bool opened
= f
.open(QIODevice::WriteOnly
);
1989 f
.write(QString("testing that remove closes the file first...").toLatin1());
1993 QFile
f("remove_unclosed.txt");
1994 bool opened
= f
.open(QIODevice::ReadOnly
);
1997 // this used to only fail on FreeBSD (and Mac OS X)
1999 bool removed
= f
.remove(); // remove should both close and remove the file
2001 QVERIFY(!f
.isOpen());
2002 QVERIFY(!f
.exists());
2003 QVERIFY(f
.error() == QFile::NoError
);
2007 void tst_QFile::fullDisk()
2009 QFile
file("/dev/full");
2011 QSKIP("/dev/full doesn't exist on this system", SkipAll
);
2013 QVERIFY(file
.open(QIODevice::WriteOnly
));
2014 file
.write("foobar", 6);
2016 QVERIFY(!file
.flush());
2017 QCOMPARE(file
.error(), QFile::ResourceError
);
2018 QVERIFY(!file
.flush());
2019 QCOMPARE(file
.error(), QFile::ResourceError
);
2023 QVERIFY(!file
.flush());
2024 QCOMPARE(file
.error(), QFile::ResourceError
);
2026 QVERIFY(!file
.flush());
2027 QCOMPARE(file
.error(), QFile::ResourceError
);
2030 QVERIFY(!file
.isOpen());
2031 QCOMPARE(file
.error(), QFile::ResourceError
);
2032 file
.open(QIODevice::WriteOnly
);
2033 QCOMPARE(file
.error(), QFile::NoError
);
2035 QCOMPARE(file
.error(), QFile::NoError
);
2037 // try again without flush:
2038 QVERIFY(file
.open(QIODevice::WriteOnly
));
2039 file
.write("foobar", 6);
2041 QVERIFY(file
.error() != QFile::NoError
);
2044 void tst_QFile::writeLargeDataBlock_data()
2046 QTest::addColumn
<QString
>("fileName");
2047 QTest::addColumn
<int>("type");
2049 QTest::newRow("localfile-QFile") << "./largeblockfile.txt" << (int)OpenQFile
;
2050 QTest::newRow("localfile-Fd") << "./largeblockfile.txt" << (int)OpenFd
;
2051 QTest::newRow("localfile-Stream") << "./largeblockfile.txt" << (int)OpenStream
;
2053 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2054 // Some semi-randomness to avoid collisions.
2055 QTest::newRow("unc file")
2056 << QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
2057 .arg(QHostInfo::localHostName())
2058 .arg(QTime::currentTime().msec()) << (int)OpenQFile
;
2062 static QByteArray
getLargeDataBlock()
2064 static QByteArray array
;
2068 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
2069 int resizeSize
= 1024 * 1024; // WinCE and Symbian do not have much space
2071 int resizeSize
= 64 * 1024 * 1024;
2073 array
.resize(resizeSize
);
2074 for (int i
= 0; i
< array
.size(); ++i
)
2075 array
[i
] = uchar(i
);
2081 void tst_QFile::writeLargeDataBlock()
2083 QFETCH(QString
, fileName
);
2084 QFETCH( int, type
);
2086 QByteArray
const originalData
= getLargeDataBlock();
2089 QFile
file(fileName
);
2091 QVERIFY2( openFile(file
, QIODevice::WriteOnly
, (FileType
)type
),
2092 qPrintable(QString("Couldn't open file for writing: [%1]").arg(fileName
)) );
2093 QCOMPARE( file
.write(originalData
), (qint64
)originalData
.size() );
2094 QVERIFY( file
.flush() );
2099 QByteArray readData
;
2102 QFile
file(fileName
);
2104 QVERIFY2( openFile(file
, QIODevice::ReadOnly
, (FileType
)type
),
2105 qPrintable(QString("Couldn't open file for reading: [%1]").arg(fileName
)) );
2106 readData
= file
.readAll();
2110 QCOMPARE( readData
, originalData
);
2111 QVERIFY( QFile::remove(fileName
) );
2114 void tst_QFile::readFromWriteOnlyFile()
2116 QFile
file("writeonlyfile");
2117 QVERIFY(file
.open(QFile::WriteOnly
));
2119 QTest::ignoreMessage(QtWarningMsg
, "QIODevice::read: WriteOnly device");
2120 QCOMPARE(file
.read(&c
, 1), qint64(-1));
2123 void tst_QFile::writeToReadOnlyFile()
2125 QFile
file("readonlyfile");
2126 QVERIFY(file
.open(QFile::ReadOnly
));
2128 QTest::ignoreMessage(QtWarningMsg
, "QIODevice::write: ReadOnly device");
2129 QCOMPARE(file
.write(&c
, 1), qint64(-1));
2132 void tst_QFile::virtualFile()
2134 // test if QFile works with virtual files
2136 #if defined(Q_OS_LINUX)
2137 fname
= "/proc/self/maps";
2138 #elif defined(Q_OS_AIX)
2139 fname
= QString("/proc/%1/map").arg(getpid());
2140 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
2141 fname
= "/proc/curproc/map";
2143 QSKIP("This platform does not have 0-sized virtual files", SkipAll
);
2146 // consistency check
2147 QFileInfo
fi(fname
);
2148 QVERIFY(fi
.exists());
2149 QVERIFY(fi
.isFile());
2150 QCOMPARE(fi
.size(), Q_INT64_C(0));
2154 QVERIFY(f
.open(QIODevice::ReadOnly
));
2155 QCOMPARE(f
.size(), Q_INT64_C(0));
2159 QByteArray data
= f
.read(16);
2160 QCOMPARE(data
.size(), 16);
2161 QCOMPARE(f
.pos(), Q_INT64_C(16));
2164 data
= f
.readLine();
2165 QVERIFY(!data
.isEmpty());
2169 QVERIFY(f
.pos() != 0);
2170 QVERIFY(!data
.isEmpty());
2174 QCOMPARE(f
.pos(), Q_INT64_C(1));
2177 void tst_QFile::textFile()
2179 #if defined(Q_OS_WINCE)
2180 FILE *fs
= ::fopen((QCoreApplication::applicationDirPath() + "/writeabletextfile").toAscii() , "wt");
2181 #elif defined(Q_OS_WIN)
2182 FILE *fs
= ::fopen("writeabletextfile", "wt");
2184 FILE *fs
= ::fopen("writeabletextfile", "w");
2187 QByteArray
part1("This\nis\na\nfile\nwith\nnewlines\n");
2188 QByteArray
part2("Add\nsome\nmore\nnewlines\n");
2190 QVERIFY(f
.open(fs
, QIODevice::WriteOnly
));
2196 QFile
file("writeabletextfile");
2197 QVERIFY(file
.open(QIODevice::ReadOnly
));
2199 QByteArray data
= file
.readAll();
2201 QByteArray expected
= part1
+ part2
;
2203 expected
.replace("\n", "\015\012");
2205 QCOMPARE(data
, expected
);
2210 void tst_QFile::rename_data()
2212 QTest::addColumn
<QString
>("source");
2213 QTest::addColumn
<QString
>("destination");
2214 QTest::addColumn
<bool>("result");
2216 QTest::newRow("a -> b") << QString("a") << QString("b") << false;
2217 QTest::newRow("a -> .") << QString("a") << QString(".") << false;
2218 QTest::newRow("renamefile -> renamefile") << QString("renamefile") << QString("renamefile") << false;
2219 QTest::newRow("renamefile -> Makefile") << QString("renamefile") << QString("Makefile") << false;
2220 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
2221 QTest::newRow("renamefile -> /etc/renamefile") << QString("renamefile") << QString("/etc/renamefile") << false;
2223 QTest::newRow("renamefile -> renamedfile") << QString("renamefile") << QString("renamedfile") << true;
2224 QTest::newRow("renamefile -> ..") << QString("renamefile") << QString("..") << false;
2227 void tst_QFile::rename()
2229 QFETCH(QString
, source
);
2230 QFETCH(QString
, destination
);
2231 QFETCH(bool, result
);
2233 QFile::remove("renamedfile");
2234 QFile
f("renamefile");
2235 f
.open(QFile::WriteOnly
);
2239 QCOMPARE(file
.rename(destination
), result
);
2241 QCOMPARE(file
.error(), QFile::NoError
);
2243 QCOMPARE(file
.error(), QFile::RenameError
);
2245 QFile::remove("renamefile");
2251 Some special files have QFile::atEnd() returning true, even though there is
2252 more data available. True for corner cases, as well as some mounts on OS X.
2254 Here, we reproduce that condition by having a QFile sub-class with this
2255 peculiar atEnd() behavior.
2259 void tst_QFile::renameWithAtEndSpecialFile() const
2261 class PeculiarAtEnd
: public QFile
2264 virtual bool atEnd() const
2270 const QString
newName(QLatin1String("newName.txt"));
2271 /* Cleanup, so we're a bit more robust. */
2272 QFile::remove(newName
);
2274 const QString
originalName(QString(SRCDIR
"forRenaming.txt"));
2277 file
.setFileName(originalName
);
2278 QVERIFY(file
.open(QIODevice::ReadOnly
));
2280 QVERIFY(file
.rename(newName
));
2283 /* Guess what, we have to rename it back, otherwise we'll fail on second
2285 QVERIFY(QFile::rename(newName
, originalName
));
2288 void tst_QFile::renameFallback()
2290 // Using a resource file both to trigger QFile::rename's fallback handling
2291 // and as a *read-only* source whose move should fail.
2292 QFile
file(":/rename-fallback.qrc");
2293 QVERIFY(file
.exists() && "(test-precondition)");
2294 QFile::remove("file-rename-destination.txt");
2296 QVERIFY(!file
.rename("file-rename-destination.txt"));
2297 QVERIFY(!QFile::exists("file-rename-destination.txt"));
2298 QVERIFY(!file
.isOpen());
2301 void tst_QFile::renameMultiple()
2303 // create the file if it doesn't exist
2304 QFile
file("file-to-be-renamed.txt");
2305 QFile
file2("existing-file.txt");
2306 QVERIFY(file
.open(QIODevice::ReadWrite
) && "(test-precondition)");
2307 QVERIFY(file2
.open(QIODevice::ReadWrite
) && "(test-precondition)");
2309 // any stale files from previous test failures?
2310 QFile::remove("file-renamed-once.txt");
2311 QFile::remove("file-renamed-twice.txt");
2314 QVERIFY(QFile::exists("existing-file.txt"));
2315 QVERIFY(!file
.rename("existing-file.txt"));
2316 QCOMPARE(file
.error(), QFile::RenameError
);
2317 QCOMPARE(file
.fileName(), QString("file-to-be-renamed.txt"));
2319 QVERIFY(file
.rename("file-renamed-once.txt"));
2320 QVERIFY(!file
.isOpen());
2321 QCOMPARE(file
.fileName(), QString("file-renamed-once.txt"));
2323 QVERIFY(QFile::exists("existing-file.txt"));
2324 QVERIFY(!file
.rename("existing-file.txt"));
2325 QCOMPARE(file
.error(), QFile::RenameError
);
2326 QCOMPARE(file
.fileName(), QString("file-renamed-once.txt"));
2328 QVERIFY(file
.rename("file-renamed-twice.txt"));
2329 QVERIFY(!file
.isOpen());
2330 QCOMPARE(file
.fileName(), QString("file-renamed-twice.txt"));
2332 QVERIFY(QFile::exists("existing-file.txt"));
2333 QVERIFY(!QFile::exists("file-to-be-renamed.txt"));
2334 QVERIFY(!QFile::exists("file-renamed-once.txt"));
2335 QVERIFY(QFile::exists("file-renamed-twice.txt"));
2339 QVERIFY(!QFile::exists("file-renamed-twice.txt"));
2340 QVERIFY(!QFile::exists("existing-file.txt"));
2343 void tst_QFile::appendAndRead()
2345 QFile
writeFile(QLatin1String("appendfile.txt"));
2346 QVERIFY(writeFile
.open(QIODevice::WriteOnly
| QIODevice::Truncate
));
2348 QFile
readFile(QLatin1String("appendfile.txt"));
2349 QVERIFY(readFile
.open(QIODevice::ReadOnly
));
2351 // Write to the end of the file, then read that character back, and so on.
2352 for (int i
= 0; i
< 100; ++i
) {
2354 writeFile
.putChar(char(i
% 256));
2356 QVERIFY(readFile
.getChar(&c
));
2357 QCOMPARE(c
, char(i
% 256));
2358 QCOMPARE(readFile
.pos(), writeFile
.pos());
2361 // Write blocks and read them back
2362 for (int j
= 0; j
< 18; ++j
) {
2363 writeFile
.write(QByteArray(1 << j
, '@'));
2365 QCOMPARE(readFile
.read(1 << j
).size(), 1 << j
);
2368 QFile::remove(QLatin1String("appendfile.txt"));
2371 void tst_QFile::miscWithUncPathAsCurrentDir()
2373 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2374 QString current
= QDir::currentPath();
2375 QVERIFY(QDir::setCurrent("//" + QtNetworkSettings::winServerName() + "/testsharewritable"));
2376 QFile
file("test.pri");
2377 QVERIFY(file
.exists());
2378 QCOMPARE(int(file
.size()), 34);
2379 QVERIFY(file
.open(QIODevice::ReadOnly
));
2380 QVERIFY(QDir::setCurrent(current
));
2384 void tst_QFile::standarderror()
2387 bool ok
= f
.open(stderr
, QFile::WriteOnly
);
2392 void tst_QFile::handle()
2395 QFile
file(SRCDIR
"tst_qfile.cpp");
2396 QVERIFY(file
.open(QIODevice::ReadOnly
));
2397 int fd
= int(file
.handle());
2399 QCOMPARE(int(file
.handle()), fd
);
2401 QT_READ(int(file
.handle()), &c
, 1);
2404 // test if the QFile and the handle remain in sync
2405 QVERIFY(file
.getChar(&c
));
2408 // same, but read from QFile first now
2410 QVERIFY(file
.open(QIODevice::ReadOnly
| QIODevice::Unbuffered
));
2411 fd
= int(file
.handle());
2413 QVERIFY(file
.getChar(&c
));
2416 QCOMPARE(QT_READ(fd
, &c
, 1), ssize_t(1));
2418 QCOMPARE(QT_READ(fd
, &c
, 1), 1);
2425 FILE *fp
= fopen(SRCDIR
"tst_qfile.cpp", "r");
2426 file2
.open(fp
, QIODevice::ReadOnly
);
2427 QCOMPARE(int(file2
.handle()), int(fileno(fp
)));
2428 QCOMPARE(int(file2
.handle()), int(fileno(fp
)));
2433 fd
= QT_OPEN(SRCDIR
"tst_qfile.cpp", QT_OPEN_RDONLY
);
2434 file3
.open(fd
, QIODevice::ReadOnly
);
2435 QCOMPARE(int(file3
.handle()), fd
);
2440 void tst_QFile::readEof_data()
2442 QTest::addColumn
<QString
>("filename");
2443 QTest::addColumn
<int>("imode");
2445 QTest::newRow("buffered") << SRCDIR
"testfile.txt" << 0;
2446 QTest::newRow("unbuffered") << SRCDIR
"testfile.txt" << int(QIODevice::Unbuffered
);
2448 #if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
2449 QTest::newRow("sequential,buffered") << "/dev/null" << 0;
2450 QTest::newRow("sequential,unbuffered") << "/dev/null" << int(QIODevice::Unbuffered
);
2454 void tst_QFile::readEof()
2456 QFETCH(QString
, filename
);
2458 QIODevice::OpenMode mode
= QIODevice::OpenMode(imode
);
2461 QFile
file(filename
);
2462 QVERIFY(file
.open(QIODevice::ReadOnly
| mode
));
2463 bool isSequential
= file
.isSequential();
2464 if (!isSequential
) {
2465 QVERIFY(file
.seek(245));
2466 QVERIFY(file
.atEnd());
2470 int ret
= file
.read(buf
, sizeof buf
);
2472 QVERIFY(file
.error() == QFile::NoError
);
2473 QVERIFY(file
.atEnd());
2475 // Do it again to ensure that we get the same result
2476 ret
= file
.read(buf
, sizeof buf
);
2478 QVERIFY(file
.error() == QFile::NoError
);
2479 QVERIFY(file
.atEnd());
2483 QFile
file(filename
);
2484 QVERIFY(file
.open(QIODevice::ReadOnly
| mode
));
2485 bool isSequential
= file
.isSequential();
2486 if (!isSequential
) {
2487 QVERIFY(file
.seek(245));
2488 QVERIFY(file
.atEnd());
2491 QByteArray ret
= file
.read(10);
2492 QVERIFY(ret
.isEmpty());
2493 QVERIFY(file
.error() == QFile::NoError
);
2494 QVERIFY(file
.atEnd());
2496 // Do it again to ensure that we get the same result
2497 ret
= file
.read(10);
2498 QVERIFY(ret
.isEmpty());
2499 QVERIFY(file
.error() == QFile::NoError
);
2500 QVERIFY(file
.atEnd());
2504 QFile
file(filename
);
2505 QVERIFY(file
.open(QIODevice::ReadOnly
| mode
));
2506 bool isSequential
= file
.isSequential();
2507 if (!isSequential
) {
2508 QVERIFY(file
.seek(245));
2509 QVERIFY(file
.atEnd());
2513 int ret
= file
.readLine(buf
, sizeof buf
);
2515 QVERIFY(file
.error() == QFile::NoError
);
2516 QVERIFY(file
.atEnd());
2518 // Do it again to ensure that we get the same result
2519 ret
= file
.readLine(buf
, sizeof buf
);
2521 QVERIFY(file
.error() == QFile::NoError
);
2522 QVERIFY(file
.atEnd());
2526 QFile
file(filename
);
2527 QVERIFY(file
.open(QIODevice::ReadOnly
| mode
));
2528 bool isSequential
= file
.isSequential();
2529 if (!isSequential
) {
2530 QVERIFY(file
.seek(245));
2531 QVERIFY(file
.atEnd());
2534 QByteArray ret
= file
.readLine();
2535 QVERIFY(ret
.isNull());
2536 QVERIFY(file
.error() == QFile::NoError
);
2537 QVERIFY(file
.atEnd());
2539 // Do it again to ensure that we get the same result
2540 ret
= file
.readLine();
2541 QVERIFY(ret
.isNull());
2542 QVERIFY(file
.error() == QFile::NoError
);
2543 QVERIFY(file
.atEnd());
2547 QFile
file(filename
);
2548 QVERIFY(file
.open(QIODevice::ReadOnly
| mode
));
2549 bool isSequential
= file
.isSequential();
2550 if (!isSequential
) {
2551 QVERIFY(file
.seek(245));
2552 QVERIFY(file
.atEnd());
2556 QVERIFY(!file
.getChar(&c
));
2557 QVERIFY(file
.error() == QFile::NoError
);
2558 QVERIFY(file
.atEnd());
2560 // Do it again to ensure that we get the same result
2561 QVERIFY(!file
.getChar(&c
));
2562 QVERIFY(file
.error() == QFile::NoError
);
2563 QVERIFY(file
.atEnd());
2567 void tst_QFile::task167217()
2569 // Regression introduced in 4.3.0; after a failed stat, pos() could no
2570 // longer be calculated correctly.
2571 QFile::remove("tmp.txt");
2572 QFile
file("tmp.txt");
2573 QVERIFY(!file
.exists());
2574 QVERIFY(file
.open(QIODevice::Append
));
2575 QVERIFY(file
.exists());
2576 file
.write("qt430", 5);
2577 QVERIFY(!file
.isSequential());
2578 QCOMPARE(file
.pos(), qint64(5));
2582 #define FILESIZE 65536 * 3
2584 void tst_QFile::map_data()
2586 QTest::addColumn
<int>("fileSize");
2587 QTest::addColumn
<int>("offset");
2588 QTest::addColumn
<int>("size");
2589 QTest::addColumn
<QFile::FileError
>("error");
2591 QTest::newRow("zero") << FILESIZE
<< 0 << FILESIZE
<< QFile::NoError
;
2592 QTest::newRow("small, but 0") << FILESIZE
<< 30 << FILESIZE
- 30 << QFile::NoError
;
2593 QTest::newRow("a page") << FILESIZE
<< 4096 << FILESIZE
- 4096 << QFile::NoError
;
2594 QTest::newRow("+page") << FILESIZE
<< 5000 << FILESIZE
- 5000 << QFile::NoError
;
2595 QTest::newRow("++page") << FILESIZE
<< 65576 << FILESIZE
- 65576 << QFile::NoError
;
2596 QTest::newRow("bad size") << FILESIZE
<< 0 << -1 << QFile::ResourceError
;
2597 QTest::newRow("bad offset") << FILESIZE
<< -1 << 1 << QFile::UnspecifiedError
;
2598 QTest::newRow("zerozero") << FILESIZE
<< 0 << 0 << QFile::UnspecifiedError
;
2601 void tst_QFile::map()
2603 QFETCH(int, fileSize
);
2604 QFETCH(int, offset
);
2606 QFETCH(QFile::FileError
, error
);
2608 QString fileName
= QDir::currentPath() + '/' + "qfile_map_testfile";
2609 if (QFile::exists(fileName
)) {
2610 QVERIFY(QFile::setPermissions(fileName
,
2611 QFile::WriteOwner
| QFile::ReadOwner
| QFile::WriteUser
| QFile::ReadUser
));
2612 QFile::remove(fileName
);
2614 QFile
file(fileName
);
2616 // invalid, not open
2617 uchar
*memory
= file
.map(0, size
);
2619 QCOMPARE(file
.error(), QFile::PermissionsError
);
2620 QVERIFY(!file
.unmap(memory
));
2621 QCOMPARE(file
.error(), QFile::PermissionsError
);
2624 QVERIFY(file
.open(QFile::ReadWrite
));
2625 QVERIFY(file
.resize(fileSize
));
2626 QVERIFY(file
.flush());
2628 QVERIFY(file
.open(QFile::ReadWrite
));
2629 memory
= file
.map(offset
, size
);
2630 if (error
!= QFile::NoError
) {
2632 QVERIFY(file
.error() != QFile::NoError
);
2636 QCOMPARE(file
.error(), error
);
2639 QVERIFY(file
.unmap(memory
));
2640 QCOMPARE(file
.error(), QFile::NoError
);
2642 // Verify changes were saved
2643 memory
= file
.map(offset
, size
);
2644 QCOMPARE(file
.error(), QFile::NoError
);
2646 QVERIFY(memory
[0] == 'Q');
2647 QVERIFY(file
.unmap(memory
));
2648 QCOMPARE(file
.error(), QFile::NoError
);
2650 // hpux wont let you map multiple times.
2651 #if !defined(Q_OS_HPUX) && !defined(Q_USE_DEPRECATED_MAP_API)
2652 // exotic test to make sure that multiple maps work
2653 uchar
*memory1
= file
.map(0, file
.size());
2654 QCOMPARE(file
.error(), QFile::NoError
);
2655 uchar
*memory2
= file
.map(0, file
.size());
2656 QCOMPARE(file
.error(), QFile::NoError
);
2659 QVERIFY(file
.unmap(memory1
));
2660 QCOMPARE(file
.error(), QFile::NoError
);
2661 QVERIFY(file
.unmap(memory2
));
2662 QCOMPARE(file
.error(), QFile::NoError
);
2663 memory1
= file
.map(0, file
.size());
2664 QCOMPARE(file
.error(), QFile::NoError
);
2666 QVERIFY(file
.unmap(memory1
));
2667 QCOMPARE(file
.error(), QFile::NoError
);
2672 #if defined(Q_OS_SYMBIAN)
2673 if (false) // No permissions for user makes no sense in Symbian
2674 #elif defined(Q_OS_UNIX)
2675 if (::getuid() != 0)
2676 // root always has permissions
2679 // Change permissions on a file, just to confirm it would fail
2680 QFile::Permissions originalPermissions
= file
.permissions();
2681 QVERIFY(file
.setPermissions(QFile::ReadOther
));
2682 QVERIFY(!file
.open(QFile::ReadWrite
));
2683 memory
= file
.map(offset
, size
);
2684 QCOMPARE(file
.error(), QFile::PermissionsError
);
2686 QVERIFY(file
.setPermissions(originalPermissions
));
2689 QVERIFY(file
.remove());
2692 void tst_QFile::mapResource_data()
2694 QTest::addColumn
<int>("offset");
2695 QTest::addColumn
<int>("size");
2696 QTest::addColumn
<QFile::FileError
>("error");
2697 QTest::addColumn
<QString
>("fileName");
2699 QString validFile
= ":/tst_qfileinfo/resources/file1.ext1";
2700 QString invalidFile
= ":/tst_qfileinfo/resources/filefoo.ext1";
2702 for (int i
= 0; i
< 2; ++i
) {
2703 QString file
= (i
== 0) ? validFile
: invalidFile
;
2704 QTest::newRow("0, 0") << 0 << 0 << QFile::UnspecifiedError
<< file
;
2705 QTest::newRow("0, BIG") << 0 << 4096 << QFile::UnspecifiedError
<< file
;
2706 QTest::newRow("-1, 0") << -1 << 0 << QFile::UnspecifiedError
<< file
;
2707 QTest::newRow("0, -1") << 0 << -1 << QFile::UnspecifiedError
<< file
;
2710 QTest::newRow("0, 1") << 0 << 1 << QFile::NoError
<< validFile
;
2713 void tst_QFile::mapResource()
2715 QFETCH(QString
, fileName
);
2716 QFETCH(int, offset
);
2718 QFETCH(QFile::FileError
, error
);
2720 QFile
file(fileName
);
2721 uchar
*memory
= file
.map(offset
, size
);
2722 QCOMPARE(file
.error(), error
);
2723 QVERIFY((error
== QFile::NoError
) ? (memory
!= 0) : (memory
== 0));
2724 if (error
== QFile::NoError
)
2725 QCOMPARE(QString(memory
[0]), QString::number(offset
+ 1));
2726 QVERIFY(file
.unmap(memory
));
2729 void tst_QFile::mapOpenMode_data()
2731 QTest::addColumn
<int>("openMode");
2733 QTest::newRow("ReadOnly") << int(QIODevice::ReadOnly
);
2734 //QTest::newRow("WriteOnly") << int(QIODevice::WriteOnly); // this doesn't make sense
2735 QTest::newRow("ReadWrite") << int(QIODevice::ReadWrite
);
2736 QTest::newRow("ReadOnly,Unbuffered") << int(QIODevice::ReadOnly
| QIODevice::Unbuffered
);
2737 QTest::newRow("ReadWrite,Unbuffered") << int(QIODevice::ReadWrite
| QIODevice::Unbuffered
);
2740 void tst_QFile::mapOpenMode()
2742 QFETCH(int, openMode
);
2743 static const qint64 fileSize
= 4096;
2744 QByteArray
pattern(fileSize
, 'A');
2746 QString fileName
= QDir::currentPath() + '/' + "qfile_map_testfile";
2747 if (QFile::exists(fileName
)) {
2748 QVERIFY(QFile::setPermissions(fileName
,
2749 QFile::WriteOwner
| QFile::ReadOwner
| QFile::WriteUser
| QFile::ReadUser
));
2750 QFile::remove(fileName
);
2752 QFile
file(fileName
);
2755 QVERIFY(file
.open(QFile::ReadWrite
));
2756 QVERIFY(file
.write(pattern
));
2757 QVERIFY(file
.flush());
2760 // open according to our mode
2761 QVERIFY(file
.open(QIODevice::OpenMode(openMode
)));
2763 uchar
*memory
= file
.map(0, fileSize
);
2765 QVERIFY(memcmp(memory
, pattern
, fileSize
) == 0);
2767 if (openMode
& QIODevice::WriteOnly
) {
2768 // try to write to the file
2772 file
.open(QIODevice::OpenMode(openMode
));
2775 QVERIFY(file
.getChar(&c
));
2782 void tst_QFile::openDirectory()
2784 QFile
f1("resources");
2785 QVERIFY(!f1
.open(QIODevice::ReadOnly
));
2787 QVERIFY(!f1
.open(QIODevice::ReadOnly
|QIODevice::Unbuffered
));
2790 void tst_QFile::openStandardStreams()
2792 // Using file descriptors
2795 in
.open(STDIN_FILENO
, QIODevice::ReadOnly
);
2796 QCOMPARE( in
.pos(), (qint64
)0 );
2797 QCOMPARE( in
.size(), (qint64
)0 );
2798 QVERIFY( in
.isSequential() );
2803 out
.open(STDOUT_FILENO
, QIODevice::WriteOnly
);
2804 QCOMPARE( out
.pos(), (qint64
)0 );
2805 QCOMPARE( out
.size(), (qint64
)0 );
2806 QVERIFY( out
.isSequential() );
2811 err
.open(STDERR_FILENO
, QIODevice::WriteOnly
);
2812 QCOMPARE( err
.pos(), (qint64
)0 );
2813 QCOMPARE( err
.size(), (qint64
)0 );
2814 QVERIFY( err
.isSequential() );
2820 in
.open(stdin
, QIODevice::ReadOnly
);
2821 QCOMPARE( in
.pos(), (qint64
)0 );
2822 QCOMPARE( in
.size(), (qint64
)0 );
2823 QVERIFY( in
.isSequential() );
2828 out
.open(stdout
, QIODevice::WriteOnly
);
2829 QCOMPARE( out
.pos(), (qint64
)0 );
2830 QCOMPARE( out
.size(), (qint64
)0 );
2831 QVERIFY( out
.isSequential() );
2836 err
.open(stderr
, QIODevice::WriteOnly
);
2837 QCOMPARE( err
.pos(), (qint64
)0 );
2838 QCOMPARE( err
.size(), (qint64
)0 );
2839 QVERIFY( err
.isSequential() );
2843 QTEST_MAIN(tst_QFile
)
2844 #include "tst_qfile.moc"