`
maricoliu
  • 浏览: 54231 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Objective-C文件操作

阅读更多

 

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.

Contents

 
 

 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程序设计

    第7章到第10章讲述objective-c的基础框架,以及文件操作、内存管理、数据保存等内容。第11章讲述了应用工具框架。第12、13章分别讲述了如何开发iphone/ipad应用程序。第14章讲述了objective-c++和访问mysql数据库的...

    《Objective-C2.0程序设计(原书第2版)》_中文完整版

    第二部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective-C的快速参考。 ...

    Objective-C 2.0程序设计

    部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归 档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective- C的快速参考。  本书结构...

    《Objective-C 2.0程序设计(原书第2版)》[PDF]

    第二部分详细阐述了foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了cocoa和iphone sdk;第四部分是附录,主要列出了objective-c的快速参考。. 本书结构...

    Programming in Objective-C, 4th Edition

    第二部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective-C的快速参考。 ...

    [Objective-c程序设计].杨正洪等.扫描版

    第7章到第10章讲述Objective-C的基础框架,以及文件操作、内存管理、数据保存等内容。第11章讲述了应用工具框架。第12、13章分别讲述了如何开发iPhone/iPad应用程序。第14章讲述了Objective-C++和访问Mysql数据库的...

    Objective-C2.0程序设计

    16.3 基本的文件操作:NSFileHandle 16.4 练习 第17章 内存管理 17.1 自动释放池 17.2 引用计数 17.2.1 引用计数和字符串 17.2.2 引用计数与实例变量 17.3 自动释放池示例 17.4 内存管理规则摘要 17.5 垃圾回收 ...

    Objective-C基础教程(第2版)

    全面系统地讲述了Objective-C的基础知识和面向对象编程的重要概念,结合实例介绍了Cocoa工具包的优秀特性及框架,以及继承、复合、对象初始化、类别、协议、内存管理和源文件组织等重要编程技术,教你如何针对iOS或...

    基于Objective-C的iOS自定义播放器设计源码

    本项目是一个基于Objective-C语言开发的iOS自定义播放器,包含44个文件,主要文件类型包括图片、MATLAB脚本、头文件、视频文件、配置文件、JSON配置文件、字符串文件、Git忽略文件、项目文件和Workspace数据文件。...

    objective-c 文件管理 实现剪贴板

    本人自己所写,借助NSFileManager和NSMutableData 实现文件的基本操作, 一个是单个文件的操作, 一个是多个文件的操作。 使用时可能需要文件路径修改一下。 欢迎之处写的不足之处。

    MYPerformanceKit 项目中会记录有关 Objective-C系统文件归类整理;.zip

    MYPerformanceKit 项目中会记录有关 Objective-C 日常常用的一些工具类和一些常用的 demo 等等;效率工具类 & 系统文件归类整理; 软件开发设计:应用软件开发、系统软件开发、移动应用开发、网站开发C++、Java...

    object-c程序设计第四版

    第7章到第10章讲述Objective-C的基础框架,以及文件操作、内存管理、数据保存等内容。第11章讲述了应用工具框架。第12、13章分别讲述了如何开发iPhone/iPad应用程序。第14章讲述了Objective-C++和访问Mysql数据库的...

    基于Object-C语言实现列表选择(项目源码).rar

    Object-C语言基础: 学习Object-C语言的基本语法和特性,了解Objective-C编程范式和iOS开发规范。 列表选择功能实现: 掌握实现iOS应用中列表选择功能的方法和技巧,包括列表的展示、数据的加载和选择状态的管理等...

    仿百度传课iOS版,版本号2.4.1.2,使用 Objective-C 语言编写.zip

    仿百度传课iOS版,版本号2.4.1.2,使用 Objective-C 语言编写,除系统自动创建的初始化页面外,其他页面都是使用纯代码编写,没有任何布局文件 软件开发设计:PHP、QT、应用软件开发、系统软件开发、移动应用开发、...

    Tosti:没有C支持的Objective-C解释器

    关于Tosti可以在运行时读取和评估Objective-C源代码,而无需将其编译为二进制文件或进行任何低级的摆弄。 它支持Objective-C在C之上添加的许多语法,但几乎不支持纯C。这意味着您可以运行以下简单内容: id a = @...

    基于RISC-V 的开源微控制器系统_C语言_Objective-C_SystemVerilog_代码_相关文件_下载

    它实现了几个 ISA 扩展,例如:硬件循环、后递增加载和存储指令、位操作指令、MAC 操作、支持定点操作、打包 SIMD 指令和点积。它旨在提高超低功耗信号处理应用的能效。RISCY 实现了 1.9 特权规范的一个子集。 zero...

Global site tag (gtag.js) - Google Analytics