1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
|
#ifndef File_h
#define File_h
/******************************************************************************
*
* Copyright (C) 2002 Hugo PEREIRA <mailto: hugo.pereira@free.fr>
*
* This 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.
*
* This software 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
*******************************************************************************/
#include "TimeStamp.h"
#include <QFileInfo>
#include <QList>
#include <QString>
#include <QTextStream>
//* file manipulation utility
class File
{
public:
//* shortcut to list of files
using List=QList<File>;
//* return list of files in a directory
enum ListFlag
{
None = 0,
Recursive = 1<<0,
FollowLinks = 1<<1,
ShowHiddenFiles = 1<<2
};
Q_DECLARE_FLAGS(ListFlags, ListFlag)
//* universal constructor
template<typename... Args>
explicit File(Args&&... args):
value_( std::forward<Args>(args)... )
{}
//* destructor
virtual ~File() = default;
//*@name accessors
//@{
//* convert to string
operator const QString& () const { return value_; }
//* accessor
const QString& get() const { return value_; }
template<class T>
bool startsWith( const T& t ) const
{ return value_.startsWith( t ); }
template<class T>
bool endsWith( const T& t ) const
{ return value_.endsWith( t ); }
template<typename... Args>
bool contains( Args&&... args ) const
{ return value_.contains( args... ); }
//* true if empty
bool isEmpty() const { return value_.isEmpty(); }
//* returns true if file has absolute pathname
bool isAbsolute() const
{ return isAbsolute( value_ ); }
//* time of file creation
TimeStamp created() const;
//* time of file last modification
TimeStamp lastModified() const;
//* time of file last access
TimeStamp lastAccessed() const;
//* user id
uint userId() const;
//* group id
uint groupId() const;
//* user name
QString userName() const;
//* group name
QString groupName() const;
//* permissions
QFile::Permissions permissions() const;
//* permission string
QString permissionsString() const
{ return permissionsString( permissions() ); }
//* permission string
QString permissionsString( const QFile::Permissions& ) const;
//* file size
qint64 fileSize() const;
//* file size (string version)
QString sizeString() const
{ return sizeString( fileSize() ); }
//* file size (string version)
static QString sizeString( qint64 );
//* raw file size
static QString rawSizeString( qint64 );
//* tells if a file exists
bool exists() const;
//* tells if a file exists and can be written into
bool isWritable() const;
//* tells if a file exists and can be written into
bool isReadOnly() const
{ return !isWritable(); }
//* tells if a file exists and is a directory
bool isDirectory() const;
//* tells if a file is hidden
bool isHidden() const;
//* tells if a file is a symbolic link
bool isLink() const;
//* tells if a file is a broken symbolic link
bool isBrokenLink() const;
//* returns true if two file differs
bool diff( const File& ) const;
//* returns true if file is the same as argument
/*
this is a literal string comparison for files.
for pathnames, the trailing backslash is ignored
*/
bool isEqual( const File& ) const;
//* get path associated to full name
File path( bool absolute = true ) const;
//* remove path from full name
File localName() const;
//* return canonical name (follow links and remove ".." and ".")
File canonicalName() const;
//* get file extension
File extension() const;
//* get truncated file (no extension)
File truncatedName() const;
//* return first file with matching short name, or empty string if not found
/** search recursively in this directory and subdirectories */
File find( const File& file, bool = true ) const;
//* find file matching this (assuming short name) in list of directries or empty if not found
File find( const List& ) const;
//* return list of files in a directory
List listFiles( ListFlags flags ) const;
//* expand a file name replacing .. or ~ to full path
File expanded() const
{ return File(*this).expand(); }
//@}
//*@name modifiers
//@{
//* accessor
QString& get() { return value_; }
//* clear
void clear() { value_.clear(); }
//* try create
bool create() const;
//* try create directory
bool createDirectory( const File& = File(".") ) const;
//* set file as hidden (WIN32 only)
void setHidden() const;
//* returns a versioned filename
/** (add _i at the end with i the first integer for which file is not found) */
File version() const;
//* make a backup copy (terminated by ~) of a file, returns backup file
File backup() const;
//* return link destination file
File readLink() const;
//* removes file from disk
/**
returns true if the file does not exists
or was successfully removed
*/
bool remove() const;
//* removes directory from disk, recursively
bool removeRecursive() const;
//* rename file
/** returns true if the file exists and was renamed */
bool rename( const File& ) const;
//* copy
bool copy( const File&, bool = false ) const;
//* adds path to a file
/** note: the file is taken raw. No truncation/expension performed.*/
File& addPath( const File& path, bool absolute = false )
{
addPath( value_, path, absolute );
return *this;
}
//* expand a file name replacing .. or ~ to full path
File& expand()
{
expand( value_ );
return *this;
}
//* add trailing slash
File& addTrailingSlash()
{ addTrailingSlash( value_ ); return *this; }
//* remove trailing slash
File& removeTrailingSlash()
{ removeTrailingSlash( value_ ); return *this; }
//@}
//*@name utilities
//@{
static bool isAbsolute( const QString& );
static void expand( QString& );
static void addTrailingSlash( QString& );
static void removeTrailingSlash( QString& );
static void addPath( QString& file, const QString& path, bool absolute = false );
//@}
//* used to find files pointing to the same link
class SameLinkFTor
{
public:
//* constructor
explicit SameLinkFTor( const File& file ):
file_( file.readLink() )
{}
//* predicate
bool operator() ( const File& file ) const
{ return file.readLink().get() == file_; }
private:
//* predicted file
QString file_;
};
//* streamer
friend QTextStream& operator >> ( QTextStream& in, File& file )
{
in >> file.value_;
return in;
}
//* streamer
friend QTextStream& operator >> ( QTextStream& out, const File& file )
{
out << file.value_;
return out;
}
private:
//* value
QString value_;
};
//* less than operator
inline bool operator < (const File& first, const File& second)
{ return first.get() < second.get(); }
//* equal to operator
inline bool operator == (const File& first, const File& second)
{ return first.get() == second.get(); }
// specialized copy constructor
template<> File::File<File&>( File& );
template<> File::File<const File&>( const File& );
Q_DECLARE_OPERATORS_FOR_FLAGS( File::ListFlags )
#endif
|