Working with Directories in Objective-C
WorkingwithDirectoriesinObjective-C
originaladdress:http://www.techotopia.com/index.php/Working_with_Directories_in_Objective-C
Akeyelementofgainingproficiencyinanyprogramminglanguageinvolvestheabilitytoworkwithfilesandfilesystems.Thelevelofdifficultyinworkingwithfilesvariesfromveryeasytohard,dependingontheprogramminglanguageconcerned.TheCprogramminglanguage,onwhichObjective-Cisbased,tendedtomakefilehandlingalittlehardrelativetothestandardsoftoday'sprogrammerfriendlyobjectorientedlanguages.ThegoodnewsforObjective-CdevelopersisthattheFoundationFrameworkincludesanumberofclassesdesignedspecificallytomakethetaskofworkingwithfilesanddirectoriesasstraightforwardaspossible.
InthischapterwewilllookattheseclassesandprovideexamplesofhowusethemtoperformsomebasicdirectoryoperationsfromwithinanObjective-Cprogram.InWorkingwithFilesinObjective-Cwewilltakeacloselookatworkingwithfilesusingtheseclasses.
TheObjective-CNSFileManager,NSFileHandleandNSDataClasses
TheFoundationFrameworkprovidesthreeclassesthatareindispensablewhenitcomestoworkingwithfilesanddirectories:
NSFileManager-TheNSFileManagerclasscanbeusedtoperformbasicfileanddirectoryoperationssuchascreating,moving,readingandwritingfilesandreadingandsettingfileattributes.Inaddition,thisclassprovidesmethodsfor,amongstothertasks,identifyingthecurrentworkingdirectory,changingtoanewdirectory,creatingdirectoriesandlistingthecontentsofadirectory.
NSFileHandle-TheNSFileHandleclassisprovidedforperforminglowerleveloperationsonfiles,suchasseekingtoaspecificpositioninafileandreadingandwritingafile'scontentsbyaspecifiednumberofbytechunksandappendingdatatoanexistingfile.
NSData-TheNSDataclassprovidesausefulstoragebufferintowhichthecontentsofafilemayberead,orfromwhichdatamaybewrittentoafile.
UnderstandingPathnamesinObjective-C
Whenusingtheaboveclasses,pathnamesaredefinedusingtheUNIXconvention.Assucheachcomponentofapathisseparatedbyaforwardslash(/).Pathsthatdonotbeginwithaslashareinterpretedtoberelativetoacurrentworkingdirectory.Forexample,ifthecurrentworkingdirectoryis/home/objcandthepathnameismyapp/example.mthenthefileisconsideredtohaveafullpathnameof/home/objc/myapp/example.m.
Inaddition,thehomedirectoryofthecurrentusercanberepresentedusingthetilde(~)character.Forexamplethepathname~/example.mreferencesafilenamedexample.mlocatedinthehomedirectoryofthecurrentuser.Thehomedirectoryofanotherusermaybereferencedbyprefixingtheusernamewitha~.Forexample,~john/demo.mreferencesafilelocatedinthehomedirectoryofausernamedjohn.
ObtainingaReferencetotheDefaultNSFileManagerObject
TheNSFileManagerclasscontainsaclassmethodnameddefaultManagerthatisusedtoobtainareferencetotheapplication’sdefaultfilemanagerinstance:
NSFileManager *filemgr; filemgr = [NSFileManager defaultManager];
IntheaboveexamplewehavedeclaredavariablenamedfilemgrtopointtoanobjectoftypeNSFileManager,andthenrequestedapointertotheapplication’sfilemanagerandassignedittothevariable.Havingobtainedtheobjectreferencewecanbegintouseittoworkwithfilesanddirectories.
IdentifyingtheCurrentWorkingDirectory
ThecurrentworkingdirectorymaybeidentifiedusingthecurrentDirectoryPathinstancemethodofourNSFileManagerobject.ThecurrentpathisreturnedfromthemethodintheformofanNSStringobject:
NSFileManager *filemgr; NSString *currentpath; filemgr = [NSFileManager defaultManager]; currentpath = [filemgr currentDirectoryPath]; NSLog (@"Current directory is %@", currentpath);
ChangingtoaDifferentDirectory
ThecurrentworkingdirectoryofarunningObjective-CprogramcanbechangedwithacalltothechangeCurrentDirectoryPathmethod.ThedestinationdirectorypathispassedasanargumenttotheinstancemethodintheformofanNSStringobject.NotethatthismethodreturnsabooleanYESorNOresulttoindicateiftherequesteddirectorychangewassuccessfulfornot:
NSFileManager *filemgr; NSString *currentpath; filemgr = [NSFileManager defaultManager]; currentpath = [filemgr currentDirectoryPath]; NSLog (@"Current directory is %@", currentpath); if ([filemgr changeCurrentDirectoryPath: @"/temp/mydir"] == NO) NSLog (@"Cannot change directory."); currentpath = [filemgr currentDirectoryPath]; NSLog (@"Current directory is %@", currentpath);
CreatingaNewDirectory
AnewdirectoryiscreatedusingthecreateDirectoryAtURLinstancemethod,thistimepassingthroughthethroughthepathnameofthenewdirectoryasanargumentintheformofanNSURLobject.ThismethodalsotakesadditionalargumentsintheformofasetofattributesforthenewdirectoryandaBooleanvalueindicatingwhetherornotintermediatedirectoriesshouldbecreatediftheydonotalreadyexist.Specifyingnilwillusethedefaultattributes:
NSFileManager *filemgr; filemgr = [NSFileManager defaultManager]; NSURL *newDir = [NSURL fileURLWithPath:@"/tmp/mynewdir"]; [filemgr createDirectoryAtURL: newDir withIntermediateDirectories:YES attributes: nil error:nil];
ThecreateDirectoryAtURLmethodreturnsaBooleanresultindicatingthesuccessorotherwiseoftheoperation.
DeletingaDirectory
AnexistingdirectorymayberemovedfromthefilesystemusingtheremoveItemAtPathmethod,passingthoughthepathofthedirectorytoberemovedasanargument:
NSFileManager *filemgr; filemgr = [NSFileManager defaultManager]; [filemgr removeItemAtPath: @"/tmp/mynewdir" handler: nil];
RenamingorMovingaFileorDirectory
Anexistingfileordirectorymaybemoved(alsoknownasrenaming)usingthemoveItemAtURLmethod.ThismethodtakesthesourceanddestinationpathnamesasargumentsintheformofNSURLobjectsandrequiresthatthedestinationpathnotalreadyexist.Ifthetargetexists,abooleanNOresultisreturnedbythemethodtoindicatefailureoftheoperation:
NSFileManager *filemgr; filemgr = [NSFileManager defaultManager]; NSURL *oldDir = [NSURL fileURLWithPath:@"/tmp/mynewdir"]; NSURL *newDir = [NSURL fileURLWithPath:@"/tmp/mynewdir2"]; [filemgr moveItemAtURL: oldDir toURL: newDir error: nil];
GettingaDirectoryFileListing
AlistingofthefilescontainedwithinaspecifieddirectorycanbeobtainedusingthecontentsOfDirectoryAtPathmethod.ThismethodtakesthedirectorypathnameasanargumentandreturnsanNSArrayobjectcontainingthenamesofthefilesandsub-directoriesinthatdirectory:
NSFileManager *filemgr; NSString *currentpath; NSArray *filelist; int count; int i; filemgr = [NSFileManager defaultManager]; filelist = [filemgr contentsOfDirectoryAtPath: @"/tmp" error: nil]; count = [filelist count]; for (i = 0; i < count; i++) NSLog (@"%@", [filelist objectAtIndex: i]);
Whenexecutedaspartofaprogram,theabovecodeexcerptwilldisplayalistingofallthefileslocatedinthe/tmpdirectory.
GettingtheAttributesofaFileorDirectory
TheattributesofafileordirectorycanbeobtainedusingtheattributesOfItemAtPathmethod.ThistakesasargumentsthepathofthedirectoryandanoptionalNSErrorobjectintowhichinformationaboutanyerrorswillbeplaced(maybespecifiedasNULLifthisinformationisnotrequired).TheresultsarereturnedintheformofanNSDictionarydictionaryobject(fordetailsofworkingwithdictionaryobjectsrefertoObjective-CDictionaryObjects).Thekeysforthisdictionaryareasfollows:
NSFileType
NSFileTypeDirectory
NSFileTypeRegular
NSFileTypeSymbolicLink
NSFileTypeSocket
NSFileTypeCharacterSpecial
NSFileTypeBlockSpecial
NSFileTypeUnknown
NSFileSize
NSFileModificationDate
NSFileReferenceCount
NSFileDeviceIdentifier
NSFileOwnerAccountName
NSFileGroupOwnerAccountName
NSFilePosixPermissions
NSFileSystemNumber
NSFileSystemFileNumber
NSFileExtensionHidden
NSFileHFSCreatorCode
NSFileHFSTypeCode
NSFileImmutable
NSFileAppendOnly
NSFileCreationDate
NSFileOwnerAccountID
NSFileGroupOwnerAccountID
Forexample,wecanextractthecreationdate,filetypeandPOSIXpermissionsforthe/tmpdirectoryusingthefollowingcodeexcerpt:
NSFileManager *filemgr; NSDictionary *attribs; filemgr = [NSFileManager defaultManager]; attribs = [filemgr attributesOfItemAtPath: @"/tmp" error: NULL]; NSLog (@"Created on %@", [attribs objectForKey: NSFileCreationDate]); NSLog (@"File type %@", [attribs objectForKey: NSFileType]); NSLog (@"POSIX Permissions %@", [attribs objectForKey: NSFilePosixPermissions]);
WhenexecutedonaMacOSXsystem,wecanexpecttoseethefollowingoutput(notethat/tmponaMacOSXsystemisasymboliclinktoprivate/tmp):
Createdon2009-01-1407:34:32-0500
FiletypeNSFileTypeSymbolicLink
POSIXPermissions493