📄 qfile_unix.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** This program is free software; you can redistribute it and/or modify it** under the terms of the GNU General Public License as published by the** Free Software Foundation; either version 2 of the License, or (at your** option) any later version.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qplatformdefs.h"// POSIX Large File Support redefines open -> open64static inline int qt_open(const char *pathname, int flags, mode_t mode){ return ::open(pathname, flags, mode); }#if defined(open)# undef open#endif// POSIX Large File Support redefines truncate -> truncate64#if defined(truncate)# undef truncate#endif#include "qfile.h"#include <errno.h>#include <limits.h>extern const char* qt_fileerr_read;bool qt_file_access( const QString& fn, int t ){ if ( fn.isEmpty() ) return FALSE; return ::access( QFile::encodeName(fn), t ) == 0;}/*! \overload Removes the file \a fileName. Returns TRUE if successful, otherwise FALSE.*/bool QFile::remove( const QString &fileName ){ if ( fileName.isEmpty() ) {#if defined(QT_CHECK_NULL) qWarning( "QFile::remove: Empty or null file name" );#endif return FALSE; } return unlink( QFile::encodeName(fileName) ) == 0;}#if defined(O_NONBLOCK)# define HAS_ASYNC_FILEMODE# define OPEN_ASYNC O_NONBLOCK#elif defined(O_NDELAY)# define HAS_ASYNC_FILEMODE# define OPEN_ASYNC O_NDELAY#endif/*! Opens the file specified by the file name currently set, using the mode \a m. Returns TRUE if successful, otherwise FALSE. \keyword IO_Raw \keyword IO_ReadOnly \keyword IO_WriteOnly \keyword IO_ReadWrite \keyword IO_Append \keyword IO_Truncate \keyword IO_Translate The mode parameter \a m must be a combination of the following flags: \table \header \i Flag \i Meaning \row \i IO_Raw \i Raw (non-buffered) file access. \row \i IO_ReadOnly \i Opens the file in read-only mode. \row \i IO_WriteOnly \i Opens the file in write-only mode. If this flag is used with another flag, e.g. \c IO_ReadOnly or \c IO_Raw or \c IO_Append, the file is \e not truncated; but if used on its own (or with \c IO_Truncate), the file is truncated. \row \i IO_ReadWrite \i Opens the file in read/write mode, equivalent to \c (IO_ReadOnly | IO_WriteOnly). \row \i IO_Append \i Opens the file in append mode. (You must actually use \c (IO_WriteOnly | IO_Append) to make the file writable and to go into append mode.) This mode is very useful when you want to write something to a log file. The file index is set to the end of the file. Note that the result is undefined if you position the file index manually using at() in append mode. \row \i IO_Truncate \i Truncates the file. \row \i IO_Translate \i Enables carriage returns and linefeed translation for text files under Windows. \endtable The raw access mode is best when I/O is block-operated using a 4KB block size or greater. Buffered access works better when reading small portions of data at a time. \warning When working with buffered files, data may not be written to the file at once. Call flush() to make sure that the data is really written. \warning If you have a buffered file opened for both reading and writing you must not perform an input operation immediately after an output operation or vice versa. You should always call flush() or a file positioning operation, e.g. at(), between input and output operations, otherwise the buffer may contain garbage. If the file does not exist and \c IO_WriteOnly or \c IO_ReadWrite is specified, it is created. Example: \code QFile f1( "/tmp/data.bin" ); f1.open( IO_Raw | IO_ReadWrite ); QFile f2( "readme.txt" ); f2.open( IO_ReadOnly | IO_Translate ); QFile f3( "audit.log" ); f3.open( IO_WriteOnly | IO_Append ); \endcode \sa name(), close(), isOpen(), flush()*/bool QFile::open( int m ){ if ( isOpen() ) { // file already open#if defined(QT_CHECK_STATE) qWarning( "QFile::open: File already open" );#endif return FALSE; } if ( fn.isNull() ) { // no file name defined#if defined(QT_CHECK_NULL) qWarning( "QFile::open: No file name specified" );#endif return FALSE; } init(); // reset params setMode( m ); if ( !(isReadable() || isWritable()) ) {#if defined(QT_CHECK_RANGE) qWarning( "QFile::open: File access not specified" );#endif return FALSE; } bool ok = TRUE; struct stat st; if ( isRaw() ) { int oflags = O_RDONLY; if ( isReadable() && isWritable() ) oflags = O_RDWR; else if ( isWritable() ) oflags = O_WRONLY; if ( flags() & IO_Append ) { // append to end of file? if ( flags() & IO_Truncate ) oflags |= (O_CREAT | O_TRUNC); else oflags |= (O_APPEND | O_CREAT); setFlags( flags() | IO_WriteOnly ); // append implies write } else if ( isWritable() ) { // create/trunc if writable if ( flags() & IO_Truncate ) oflags |= (O_CREAT | O_TRUNC); else oflags |= O_CREAT; }#if defined(HAS_TEXT_FILEMODE) if ( isTranslated() ) oflags |= OPEN_TEXT; else oflags |= OPEN_BINARY;#endif#if defined(HAS_ASYNC_FILEMODE) if ( isAsynchronous() ) oflags |= OPEN_ASYNC;#endif fd = qt_open( QFile::encodeName(fn), oflags, 0666 ); if ( fd != -1 ) { // open successful ::fstat( fd, &st ); // get the stat for later usage } else { ok = FALSE; } } else { // buffered file I/O QCString perm; char perm2[4]; bool try_create = FALSE; if ( flags() & IO_Append ) { // append to end of file? setFlags( flags() | IO_WriteOnly ); // append implies write perm = isReadable() ? "a+" : "a"; } else { if ( isReadWrite() ) { if ( flags() & IO_Truncate ) { perm = "w+"; } else { perm = "r+"; try_create = TRUE; // try to create if not exists } } else if ( isReadable() ) { perm = "r"; } else if ( isWritable() ) { perm = "w"; } } qstrcpy( perm2, perm );#if defined(HAS_TEXT_FILEMODE) if ( isTranslated() ) strcat( perm2, "t" ); else strcat( perm2, "b" );#endif for (;;) { // At most twice fh = fopen( QFile::encodeName(fn), perm2 ); if ( !fh && try_create ) { perm2[0] = 'w'; // try "w+" instead of "r+" try_create = FALSE; } else { break; } } if ( fh ) { ::fstat( fileno(fh), &st ); // get the stat for later usage } else { ok = FALSE; } } if ( ok ) { setState( IO_Open ); // on successful open the file stat was got; now test what type // of file we have if ( (st.st_mode & S_IFMT) != S_IFREG ) { // non-seekable setType( IO_Sequential ); length = INT_MAX; ioIndex = 0; } else { length = (Offset)st.st_size; ioIndex = (flags() & IO_Append) == 0 ? 0 : length; if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) { // try if you can read from it (if you can, it's a sequential // device; e.g. a file in the /proc filesystem) int c = getch(); if ( c != -1 ) { ungetch(c); setType( IO_Sequential ); length = INT_MAX; ioIndex = 0; } resetStatus(); } } } else { init(); if ( errno == EMFILE ) // no more file handles/descrs setStatus( IO_ResourceError ); else setStatus( IO_OpenError ); setErrorStringErrno( errno ); } return ok;}/*! \overload Opens a file in the mode \a m using an existing file handle \a f. Returns TRUE if successful, otherwise FALSE. Example: \code #include <stdio.h> void printError( const char* msg ) { QFile f; f.open( IO_WriteOnly, stderr ); f.writeBlock( msg, qstrlen(msg) ); // write to stderr f.close(); } \endcode When a QFile is opened using this function, close() does not actually close the file, only flushes it. \warning If \a f is \c stdin, \c stdout, \c stderr, you may not be able to seek. See QIODevice::isSequentialAccess() for more information. \sa close()*/bool QFile::open( int m, FILE *f ){ if ( isOpen() ) {#if defined(QT_CHECK_RANGE) qWarning( "QFile::open: File already open" );#endif return FALSE; } init(); setMode( m &~IO_Raw ); setState( IO_Open ); fh = f; ext_f = TRUE; struct stat st; ::fstat( fileno(fh), &st );#if defined(QT_LARGEFILE_SUPPORT) ioIndex = (Offset)ftello( fh );#else ioIndex = (Offset)ftell( fh );#endif if ( (st.st_mode & S_IFMT) != S_IFREG || f == stdin ) { //stdin is non seekable // non-seekable setType( IO_Sequential ); length = INT_MAX;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -