I followed the Below Blog:
First we need to recap the steps necessary to obtain a reference to
creatane an instance of the NSFileManager class. As discussed in the
previous chapter, the NSFileManager class contains a class method named
defaultManager that is used to create an instance of the class. For
example:obtain a reference to the NSFileManager object instance:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
Checking if a File Exists
The NSFileManager class contains an instance method named
fileExistsAtPath
that checks whether a specified file already exists. The method takes
as an argument an NSString object containing the path to file and
returns a boolean YES or NO value indicating the presence or otherwise
of that file:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: @"/tmp/myfile.txt" ] == YES)
NSLog (@"File exists");
else
NSLog (@"File not found");
Comparing the Contents of Two Files
The contents of two files can be compared for equality using the
contentsEqualAtPath
method. This method takes as arguments the paths to the two files to be
compared and returns a boolean YES or NO to indicate whether the file
contents match:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr contentsEqualAtPath: @"/tmp/myfile.txt" andPath: @"/tmp/sales.txt"] == YES)
NSLog (@"File contents match");
else
NSLog (@"File contents do not match");
Checking if a File is Readable/Writable/Executable/Deletable
Most operating systems provide some level of file access control.
These typically take the form of attributes that control the level of
access to a file for each user or user group. As such, it is not a
certainty that your program will have read or write access to a
particular file, or the appropriate permissions to delete or execute it.
The quickest way to find out if your program has a particular access
permission is to use the
isReadableFileAtPath,
isWritableFileAtPath,
isExecutableFileAtPath and
isDeletableFileAtPath
methods. Each method takes a single argument in the form of the path to
the file to be checked and returns a boolean YES or NO result. For
example, the following code excerpt checks to find out if a file is
writable:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr isWritableFileAtPath: @"/tmp/myfile.txt"] == YES)
NSLog (@"File is writable");
else
NSLog (@"File is read only");
To check for other access permissions simply substitute the corresponding method name in place of
isWritableFileAtPath in this example.
Moving/Renaming a File
A file may be renamed (assuming adequate permissions) using the moveItemAtURL method. This
method returns
a boolean YES or NO result and takes as arguments the pathname for the
file to be moved, the destination path and an optional NSError object
into which information describing any
errors encountered
during the operation will be placed. If no error description
information is required, this argument may be set to NULL. Note that if
the destination file path already exists this operation will fail.
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSURL *oldPath = [NSURL fileURLWithPath:@"/tmp/myfile.txt"];
NSURL *newPath= [NSURL fileURLWithPath:@"/tmp/newfile.txt"];
[filemgr moveItemAtURL: oldPath toURL: newPath error: nil];
Copying a File
File copying can be achieved using the
copyItemAtPath method. As with the
move
method, this takes as arguments the source and destination pathnames
and an optional NSError object. Success of the operation is indicated by
the returned
boolean value:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr copyItemAtPath: @"/tmp/myfile.txt" toPath: @"/Users/demo/newfile.txt" error: NULL] == YES)
NSLog (@"Copy successful");
else
NSLog (@"Copy failed");
Removing a File
The
removeItemAtPath method removes the specified file from
the file system. The method takes as arguments the pathname of the file
to be removed and an optional NSError object. The success of the
operation is, as usual, reported in the form of a boolean YES or NO
return value:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr removeItemAtPath: @"/tmp/myfile.txt" error: NULL] == YES)
NSLog (@"Remove successful");
else
NSLog (@"Remove failed");
Creating a Symbolic Link
A symbolic link to a particular file may be created using the
createSymbolicLinkAtPath method. This takes as arguments the path of the
symbolic link, the path to the file to which the link is to refer and
an optional NSError object. For example, the following
code creates a symbolic link from/tmpUsers/demo/myfile21.txt that links to the pre-existing file /tmp/myfile.txt:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr createSymbolicLinkAtPath: @"/tmp/myfile2.txt"
withDestinationPath: @"/tmp/myfile.txt" error: NULL] == YES)
NSLog (@"Link successful");
else
NSLog (@"Link failed");NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr createSymbolicLinkAtPath: @"/Users/demo/file1.txt"
withDestinationPath: @"/tmp/myfile.txt" error: NULL] == YES)
NSLog (@"Remove successful");
else
NSLog (@"Remove failed");
Reading and Writing Files with NSFileManager
The NSFileManager class includes some basic file reading and writing
capabilities. these capabilities are somewhat limited when compared to
the options provided by the NSFileHandle class, but can be useful
nonetheless.
Firstly, the contents of a file may be read and stored in an NSData object through the use of the
contentsAtPath method:
NSFileManager *filemgr;
NSData *databuffer;
filemgr = [NSFileManager defaultManager];
databuffer = [filemgr contentsAtPath: @"/tmp/myfile.txt" ];
Having stored the contents of a file in an NSData object, that data may subsequently be written out to a new file using the
createFileAtPath method:
databuffer = [filemgr contentsAtPath: @"/tmp/myfile.txt" ];
[filemgr createFileAtPath: @"/tmp/newfile.txt" contents: databuffer attributes: nil];
In the above example we have essentially copied the contents from an
existing file to a new file. This, however, gives us no control over how
much data is to be read or written and does not allow us to append data
to the end of an existing file. If the file
/tmp/newfile.txt in the above example had already existed it, and any data it contained, would have been overwritten by the contents of the
source file. Clearly some more flexible mechanism is required. This is provided by the Foundation Framework in the form of the
NSFileHandle class.
Working with Files using the NSFileHandle Class
The NSFileHandle class provides a range of methods designed to
provide a more advanced mechanism for working with files. In addition to
files, this class can also be used for working with devices and network
sockets. In the following sections we will look at some of the more
common uses for this class.
Creating an NSFileHandle Object
An NSFileHandle object can be created when opening a file for
reading, writing or updating (reading and writing). This is achieved
using the
fileHandleForReadingAtPath,
fileHandleForWritingAtPath and
fileHandleForUpdatingAtPath methods respectively. Having opened a file, it must subsequently be closed when we have finished working with it using the
closeFile
method. If an attempt to open a file fails, for example because an
attempt is made to open a non-existent file for reading, these methods
return
nil.
For example, the following code excerpt opens a file for reading
and writing and then closes it without actually doing anything to the
file:
NSFileHandle *file;
file = [NSFileHandle fileHandleForWritingAtPath: @"/tmp/myfile.txt"];
if (file == nil)
NSLog(@"Failed to open file");
[file closeFile];
NSFileHandle File Offsets and Seeking
NSFileHandle objects maintain a pointer to the current position in a file. This is referred to as the
offset.
When a file is first opened the offset is set to 0 (the beginning of
the file). This means that any read or write operations we perform using
the NSFileHandle methods will take place at offset 0 in the file. To
perform operations at different locations in a file (for example to
append data to the end of the file) it is first necessary to
seek to the required offset. For example to move the current offset to the end of the file, use the
seekToEndOfFile method. Alternatively,
seekToFileOffset
allows you to specify the precise location in the file to which the
offset is to be positioned. Finally, the current offset may be
identified using the
offsetInFile method. In order to accommodate large files, the offset is stored in the form of an unsigned long long.
The following example opens a file for reading and then performs a
number of method calls to move the offset to different positions,
outputting the current offset after each move:
NSFileHandle *file;
file = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/myfile.txt"];
if (file == nil)
NSLog(@"Failed to open file");
NSLog (@"Offset = %llu", [file offsetInFile]);
[file seekToEndOfFile];
NSLog (@"Offset = %llu", [file offsetInFile]);
[file seekToFileOffset: 30];
NSLog (@"Offset = %llu", [file offsetInFile]);
[file closeFile];
File offsets are a key aspect of working with files using the
NSFileHandle class so it is worth taking extra time to make sure you
understand the concept. Without knowing where the current offset is in a
file it is impossible to know where in the file data will be read or
written.
Reading Data from a File
Once a file has been opened and assigned a file handle, the contents
of that file may be read from the current offset position. The
readDataOfLength
method reads a specified number of bytes of data from the file starting
at the current offset. For example, the following code reads 5 bytes of
data from offset 10 in a file. The data read is returned encapsulated
in an NSData object:
NSFileHandle *file;
NSData *databuffer;
file = [NSFileHandle fileHandleForReadingAtPath: @"/tmp/myfile.txt"];
if (file == nil)
NSLog(@"Failed to open file");
[file seekToFileOffset: 10];
databuffer = [file readDataOfLength: 5];
[file closeFile];
Alternatively, the
readDataToEndOfFile method will read all the data in the file starting at the current offset and ending at the end of the file.
Writing Data to a File
The
writeData method writes the data contained in an NSData
object to the file starting at the location of the offset. Note that
this does not insert data but rather overwrites any existing data in the
file at the corresponding location.
To see this in action we need to begin with a file. Using a text
editor, create a file named quickfox.txt, enter the following text and
save it in the /tmp directory:
The quick brown fox jumped over the lazy dog
Next, we will write a program that opens the file for updating, seeks to position 10 and then writes some data at that location:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSFileHandle *file;
NSMutableData *data;
const char *bytestring = "black dog";
data = [NSMutableData dataWithBytes:bytestring length:strlen(bytestring)];
file = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/quickfox.txt"];
if (file == nil)
NSLog(@"Failed to open file");
[file seekToFileOffset: 10];
[file writeData: data];
[file closeFile];
}
return 0;
}
When the above program is compiled and executed the contents of the quickfox.txt will have changed to:
The quick black dog jumped over the lazy dog
Truncating a File
A file may be truncated at the specified offset using the
truncateFileAtOffset method. To delete the entire contents of a file, specify an offset of 0 when calling this method:
NSFileHandle *file;
file = [NSFileHandle fileHandleForUpdatingAtPath: @"/tmp/quickfox.txt"];
if (file == nil)
NSLog(@"Failed to open file");
[file truncateFileAtOffset: 0];
[file closeFile];