In the chapter entitled Working with Directories on iPhone OS we looked at the NSFileManager, NSFileHandle and NSData Foundation Framework classes and discussed how the NSFileManager class in particular enables us to work with directories when developing iPhone based applications. We also spent some time covering the file system structure used by the iPhone OS and in particular looked at the temporary and Documents directories assigned to each application and how the location of those directories can be identified from within the application code.
In this chapter we move on from working with directories to covering the details of working with files within iPhone applications. Once we have covered file handling topics in this chapter, the next chapter will work through an application example that puts theory into practice.
Creating an NSFileManager Instance
before proceeding, first we need to recap the steps necessary to create 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:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
Once the file manager object has been created it can be used to perform some basic file handling tasks.
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 the file in question and returns a boolean YES or NO value indicating the presence or otherwise of the specified file:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: @"/tmp/myfile.txt" ] == YES)
NSLog (@"File exists");
else
NSLog (@"File not found");
[filemgr release];
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");
[filemgr release];
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 rename 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");
[filemgr release];
To check for other access permissions simply substitute the corresponding method name in place of isWritableFileAtPath in the above example.
Moving/Renaming a File
A file may be renamed (assuming adequate permissions) using the moveItemAtPath 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];
if ([filemgr moveItemAtPath: @"/tmp/myfile.txt" toPath: @"/tmp/newfile.txt" error: NULL] == YES)
NSLog (@"Move successful");
else
NSLog (@"Move failed");
[filemgr release];
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:
if ([filemgr copyItemAtPath: @"/tmp/myfile.txt" toPath: @"/Users/demo/newfile.txt" error: NULL] == YES)
NSLog (@"Copy successful");
else
NSLog (@"Copy failed");
[filemgr release];
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");
[filemgr release];
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/Users/demo/file1.txt that links to the pre-existing file /tmp/myfile.txt:
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");
[filemgr release];
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];
[filemgr release];
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];
[file release];
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 release];
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:
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];
[file release];
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, let’s assume the existence of a file named quickfox.txt containing the following text:
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:
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];
[file release];
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];
[file release];
相关推荐
综上所述,本教程覆盖了Objective-C编程语言的基础知识点,不仅包括语法和结构,还包括与C语言的兼容性、内存管理机制、面向对象编程的核心概念、以及如何在不同操作系统平台上进行开发的介绍。通过这些内容的学习,...
尽管Objective-C主要与Apple的平台(如iOS和macOS)相关联,但有时候,出于某些原因(比如团队协作或个人偏好),开发者可能需要在非Apple的操作系统(如Windows)上构建Objective-C应用程序。本文将详细介绍如何在...
1. **Objective-C基础**:Objective-C是在C语言基础上扩展的,因此,理解C语言的基本语法是必要的。Objective-C添加了消息传递机制、类和协议等面向对象特性。 2. **消息传递**:Objective-C中的对象通过发送消息来...
Objective-C语法的基石是C语言的语法结构,这意味着所有的C语言代码都可以在Objective-C中直接使用。但是,Objective-C在C的基础上新增了消息传递机制,这是它与C语言的一个重要区别。在Objective-C中,方法调用是...
- **文件操作**:Objective-C 提供了读写文件的方法,可能在例子中涉及文件的保存和加载。 - **网络编程**:如何使用 NSURLSession 进行网络请求,或者使用 NSInputStream 和 NSOutputStream 处理流数据。 - **动画...
此外,还可能介绍Foundation框架的基础知识,如字符串操作、集合类(NSArray, NSDictionary等)以及文件I/O。 2. **Objective-C.2.0程序设计.pdf** Objective-C 2.0带来了许多改进,这本书会深入探讨这些新特性。这...
Objective-C是Cocoa的主要编程语言,它扩展了C语言,引入了面向对象的特性,如消息传递和类别。 本书首先会引导读者了解Objective-C的基础,包括语法、类、对象以及内存管理。然后,它会深入Cocoa的核心组件,如...
第二部分详细阐述了Foundation框架,介绍了数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容。Foundation框架是Objective-C语言中非常重要的一个组件,它提供了一组丰富的、面向对象的类,为开发...
Objective-C是一种面向对象的编程语言,它是在标准C语言的基础上发展起来的,并且完全兼容C语言。由于其面向对象的特性,Objective-C被广泛应用于苹果公司的iOS和OS X操作系统上的应用程序开发。 #### 二、...
它包含了数字、字符串、集合、文件操作等丰富的类和方法。 9. Cocoa、CocoaTouch与iOS SDK:第三部分深入介绍了Cocoa和CocoaTouch框架,这两个框架是构建Mac OS X和iOS应用程序的核心。同时,本书也涉及了iOS SDK的...
Objective-C是一种主要应用于苹果操作系统上的编程语言,它是C语言的一种扩展,支持面向对象编程特性。Objective-C最初由Pike International公司的Brad Cox和Tom Love于1983年设计,并在1986年由NEXTSTEP系统引入。...
Foundation框架是Objective-C开发的基础,提供了大量的基础数据类型、集合类(如NSArray, NSDictionary等)、线程管理、文件操作等功能。而UIKit框架则是iOS应用开发的核心,包含了视图控件、事件处理、动画等元素。...
1. **Objective-C基础**:Objective-C是C语言的超集,它引入了Smalltalk的类、消息传递等面向对象特性。了解基本的数据类型、变量声明、控制流语句(如if、for、while)以及函数定义是开始的基础。 2. **类和对象**...
从给定的文件信息来看,这是一份关于Objective-C编程语言的英文原版高质量教程,主要涉及了Objective-C的基础概念、语法结构以及如何使用该语言进行编程。Objective-C是一种通用、面向对象的编程语言,由Stepstone...
Objective-C是一种强大的面向对象编程语言,它主要应用于Apple的Mac OS X和iOS操作系统。这个基础案例集是专为初学者设计的,目的是帮助他们迅速掌握Objective-C的基本语法和概念。以下是一些关于Objective-C的关键...
在文件"RSA(objective-c )"中,可能包含了实现RSA算法的Objective-C源代码,包括密钥生成、加密和解密的函数,以及可能的测试用例。学习这个实现可以帮助你深入理解RSA算法的工作原理,并掌握在Objective-C环境下...
在压缩包`win7objectivec`中,可能包含了编译Objective-C在Windows 7上所需的一些资源、示例代码或者教程文档。如果你遇到任何问题,如编译错误或找不到库,查看这些资源通常能提供帮助。同时,确保你的系统满足所有...
- Objective-C 诞生于 NeXTSTEP 操作系统,后来随着苹果收购 NeXT,成为 Mac OS X 和 iPhone OS(现在的 iOS)的主要开发语言。 - 它是 C 语言的超集,意味着所有合法的 C 代码都是 Objective-C 的一部分,同时...