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