00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "CeylanFile.h"
00028
00029 #include "CeylanLogPlug.h"
00030 #include "CeylanDirectory.h"
00031 #include "CeylanOperators.h"
00032 #include "CeylanStringUtils.h"
00033 #include "CeylanFileSystemManager.h"
00034
00035
00036
00037 using std::string ;
00038
00039
00040 using namespace Ceylan ;
00041 using namespace Ceylan::System ;
00042 using namespace Ceylan::Log ;
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 const OpeningFlag File::Read = 0x0001 ;
00055 const OpeningFlag File::Write = 0x0002 ;
00056 const OpeningFlag File::CreateFile = 0x0004 ;
00057 const OpeningFlag File::TruncateFile = 0x0008 ;
00058 const OpeningFlag File::AppendFile = 0x0010 ;
00059 const OpeningFlag File::Binary = 0x0020 ;
00060 const OpeningFlag File::NonBlocking = 0x0040 ;
00061 const OpeningFlag File::Synchronous = 0x0080 ;
00062
00063
00064
00065
00066
00067 const OpeningFlag File::CreateToWriteBinary =
00068 Read | Write | CreateFile | TruncateFile | Binary ;
00069
00070
00071 const OpeningFlag File::OpenToReadBinary = Read | Binary ;
00072
00073
00074 const OpeningFlag File::DoNotOpen = 0xffff ;
00075
00076
00077
00078
00079
00080 const PermissionFlag File::OwnerRead = 0x0001 ;
00081 const PermissionFlag File::OwnerWrite = 0x0002 ;
00082 const PermissionFlag File::OwnerExec = 0x0004 ;
00083
00084 const PermissionFlag File::OwnerReadWrite =
00085 File::OwnerRead | File::OwnerWrite ;
00086
00087 const PermissionFlag File::OwnerReadWriteExec =
00088 File::OwnerReadWrite | File::OwnerExec ;
00089
00090
00091 const PermissionFlag File::GroupRead = 0x0008 ;
00092 const PermissionFlag File::GroupWrite = 0x0010 ;
00093 const PermissionFlag File::GroupExec = 0x0020 ;
00094
00095 const PermissionFlag File::GroupReadWrite =
00096 File::GroupRead | File::GroupWrite ;
00097
00098 const PermissionFlag File::GroupReadWriteExec =
00099 File::GroupReadWrite | File::GroupExec ;
00100
00101
00102 const PermissionFlag File::OthersRead = 0x0040 ;
00103 const PermissionFlag File::OthersWrite = 0x0080 ;
00104 const PermissionFlag File::OthersExec = 0x0100 ;
00105
00106 const PermissionFlag File::OthersReadWrite =
00107 File::OthersRead | File::OthersWrite ;
00108
00109 const PermissionFlag File::OthersReadWriteExec =
00110 File::OthersReadWrite | File::OthersExec ;
00111
00112
00113
00114 const Size File::UsualBufferSize = 10240 ;
00115 const Size File::BigBufferSize = 1<<19 ;
00116
00117
00118
00119
00120
00121
00122
00123
00124 FileReadLockingFailed::FileReadLockingFailed( const string & reason ) :
00125 FileException( reason )
00126 {
00127
00128 }
00129
00130
00131
00132 FileReadUnlockingFailed::FileReadUnlockingFailed( const string & reason ) :
00133 FileException( reason )
00134 {
00135
00136 }
00137
00138
00139
00140 FileWriteLockingFailed::FileWriteLockingFailed( const string & reason ) :
00141 FileException( reason )
00142 {
00143
00144 }
00145
00146
00147
00148 FileWriteUnlockingFailed::FileWriteUnlockingFailed( const string & reason ) :
00149 FileException( reason )
00150 {
00151
00152 }
00153
00154
00155
00156 FileDelegatingException::FileDelegatingException( const string & reason ) :
00157 FileException( reason )
00158 {
00159
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 bool File::ExistsAsFileOrSymbolicLink( const string & filename )
00172 {
00173
00174
00175 return GetCorrespondingFileSystemManager().existsAsFileOrSymbolicLink(
00176 filename ) ;
00177
00178 }
00179
00180
00181
00182 bool File::Exists( const string & filename )
00183 {
00184
00185
00186 return ExistsAsFileOrSymbolicLink( filename ) ;
00187
00188 }
00189
00190
00191
00192 void File::Remove( const string & filename )
00193 {
00194
00195
00196 GetCorrespondingFileSystemManager().removeFile( filename ) ;
00197
00198 }
00199
00200
00201
00202 void File::Move( const string & sourceFilename, const string & targetFilename )
00203 {
00204
00205
00206 GetCorrespondingFileSystemManager().moveFile( sourceFilename,
00207 targetFilename ) ;
00208
00209 }
00210
00211
00212
00213 void File::Copy( const string & sourceFilename, const string & targetFilename )
00214 {
00215
00216
00217 GetCorrespondingFileSystemManager().copyFile( sourceFilename,
00218 targetFilename ) ;
00219
00220 }
00221
00222
00223
00224 Size File::GetSize( const string & filename )
00225 {
00226
00227
00228 return GetCorrespondingFileSystemManager().getSize( filename ) ;
00229
00230 }
00231
00232
00233
00234 time_t File::GetLastChangeTime( const string & filename )
00235 {
00236
00237
00238
00239
00240
00241
00242 return GetCorrespondingFileSystemManager().getLastChangeTimeFile(
00243 filename ) ;
00244
00245 }
00246
00247
00248
00249 string File::TransformIntoValidFilename( const string & rawFilename )
00250 {
00251
00252
00253 return GetCorrespondingFileSystemManager().transformIntoValidFilename(
00254 rawFilename ) ;
00255
00256 }
00257
00258
00259
00260 void File::Touch( const string & filename )
00261 {
00262
00263
00264 GetCorrespondingFileSystemManager().touch( filename ) ;
00265
00266 }
00267
00268
00269
00270 bool File::Diff( const string & firstFilename, const string & secondFilename )
00271 {
00272
00273
00274 return GetCorrespondingFileSystemManager().diff( firstFilename,
00275 secondFilename ) ;
00276
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 File & File::Create( const std::string & filename, OpeningFlag createFlag,
00290 PermissionFlag permissionFlag )
00291 {
00292
00293 return GetCorrespondingFileSystemManager().createFile( filename, createFlag,
00294 permissionFlag ) ;
00295
00296 }
00297
00298
00299
00300 File & File::Open( const std::string & filename, OpeningFlag openFlag )
00301 {
00302
00303 return GetCorrespondingFileSystemManager().openFile( filename, openFlag ) ;
00304
00305 }
00306
00307
00308
00309 File::~File() throw()
00310 {
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 }
00329
00330
00331
00332
00333 const std::string & File::getName() const
00334 {
00335
00336 return _name ;
00337
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347 void File::lockForReading() const
00348 {
00349
00350
00351
00352 throw FileReadLockingFailed( "File::lockForReading: "
00353 "lock feature not available" ) ;
00354
00355 }
00356
00357
00358
00359 void File::unlockForReading() const
00360 {
00361
00362
00363
00364 throw FileReadUnlockingFailed( "File::unlockForReading: "
00365 "lock feature not available" ) ;
00366
00367 }
00368
00369
00370
00371 void File::lockForWriting() const
00372 {
00373
00374
00375
00376 throw FileWriteLockingFailed( "File::lockForWriting: "
00377 "lock feature not available" ) ;
00378
00379 }
00380
00381
00382
00383 void File::unlockForWriting() const
00384 {
00385
00386
00387
00388 throw FileWriteUnlockingFailed( "File::unlockForWriting: "
00389 "lock feature not available" ) ;
00390
00391 }
00392
00393
00394
00395 bool File::isLocked() const
00396 {
00397
00398
00399
00400 return false ;
00401
00402 }
00403
00404
00405
00406 Size File::size() const
00407 {
00408
00409
00410 return getCorrespondingFileSystemManager().getSize( _name ) ;
00411
00412 }
00413
00414
00415
00416 void File::readExactLength( Ceylan::Byte * buffer, Size exactLength )
00417 {
00418
00419 Size remainder = exactLength ;
00420 Size readCount ;
00421
00422 Ceylan::Uint32 readFailures = 0 ;
00423 const Ceylan::Uint32 maxReadFailures = 10000 ;
00424
00425 try
00426 {
00427
00428 do
00429 {
00430
00431 readCount = read( buffer, remainder ) ;
00432
00433 remainder -= readCount ;
00434
00435 if ( readCount == 0 )
00436 readFailures++ ;
00437 else
00438 readFailures = 0 ;
00439
00440 }
00441 while( remainder > 0 && readFailures < maxReadFailures ) ;
00442
00443
00444 }
00445 catch ( const InputStream::ReadFailedException & e )
00446 {
00447
00448 throw InputStream::ReadFailedException(
00449 "File::readExactLength: trying to read "
00450 + Ceylan::toString( static_cast<Ceylan::Uint32>( exactLength ) )
00451 + " bytes, actually read "
00452 + Ceylan::toString( static_cast<Ceylan::Uint32>(
00453 exactLength - remainder ) )
00454 + " bytes before following error: " + e.toString() ) ;
00455
00456 }
00457
00458 if ( readFailures == maxReadFailures )
00459 throw InputStream::ReadFailedException(
00460 "File::readExactLength: unable to read requested bytes, maybe "
00461 "trying to read a binary file not opened in Binary mode?" ) ;
00462
00463 }
00464
00465
00466
00467 bool File::hasAvailableData() const
00468 {
00469
00470 return true ;
00471
00472 }
00473
00474
00475
00476
00477 void File::open( OpeningFlag openFlag, PermissionFlag permissionFlag )
00478 {
00479
00480 if ( _openFlag != DoNotOpen )
00481 throw FileAlreadyOpened( "File::open: file '" + _name
00482 + "' was already opened." ) ;
00483
00484 _openFlag = openFlag ;
00485 _permissions = permissionFlag ;
00486
00487 reopen() ;
00488
00489 }
00490
00491
00492
00493 void File::remove()
00494 {
00495
00496 try
00497 {
00498
00499 close() ;
00500
00501 }
00502 catch( const Stream::CloseException & e )
00503 {
00504 throw FileRemoveFailed( "File::remove failed: " + e.toString() ) ;
00505 }
00506
00507
00508
00509 getCorrespondingFileSystemManager().removeFile( _name ) ;
00510
00511 }
00512
00513
00514
00515 StreamID File::getInputStreamID() const
00516 {
00517
00518 return getStreamID() ;
00519
00520 }
00521
00522
00523
00524 StreamID File::getOutputStreamID() const
00525 {
00526
00527 return getStreamID() ;
00528
00529 }
00530
00531
00532
00533 const std::string File::toString( Ceylan::VerbosityLevels level )
00534 const
00535 {
00536
00537 return "File object for filename '" + _name + "'" ;
00538
00539 }
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 File::File( const string & name, OpeningFlag openFlag,
00550 PermissionFlag permissions ) :
00551 InputOutputStream(),
00552 _name( name ),
00553 _openFlag( openFlag ),
00554 _permissions( permissions ),
00555 _lockedForReading( false ),
00556 _lockedForWriting( false )
00557 {
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 }
00570
00571
00572
00573 FileSystemManager & File::GetCorrespondingFileSystemManager()
00574 {
00575
00576 try
00577 {
00578
00579 return FileSystemManager::GetAnyDefaultFileSystemManager() ;
00580
00581 }
00582 catch( const FileSystemManagerException & e )
00583 {
00584 throw FileDelegatingException(
00585 "File::GetCorrespondingFileSystemManager failed: "
00586 + e.toString() ) ;
00587 }
00588
00589 }
00590