【IOS 开发学习总结-OC-36】★文件 I/O——NSFileHandle&NSURL&NSBundle

NSFileHandle处理文件 IO

使用NSFileHandle的基本步骤如下:

  1. 创建一个NSFileHandle,该NSFileHandle将会打开指定的文件;
  2. 对打开的文件执行IO操作;
  3. 关闭文件。

NSFileHandle提供的常用方法如下:
1. + (nullable instancetype)fileHandleForReadingAtPath:(NSString *)path; 根据指定路径打开一份准备读取文件内容的文件,并返回该文件对应的NSFileHandle;
2. + (nullable instancetype)fileHandleForWritingAtPath:(NSString *)path;:根据指定路径打开一份准备写入内容的文件,并返回该文件对应的NSFileHandle;
3. + (nullable instancetype)fileHandleForUpdatingAtPath:(NSString *)path; 根据指定路径打开一份即可读取,又可写入文件内容的文件,并返回该文件对应的NSFileHandle;
4. + (nullable instancetype)fileHandleForReadingFromURL:(NSURL *)url error:(NSError **)error :; 根据指定URL打开一份准备读取文件内容的文件,并返回该文件对应的NSFileHandle;
5. + (nullable instancetype)fileHandleForWritingToURL:(NSURL *)url error:(NSError **)error NS_AVAILABLE(10_6, 4_0); 根据指定URL打开一份准备写入内容的文件,并返回该文件对应的NSFileHandle;
6. + (nullable instancetype)fileHandleForUpdatingURL:(NSURL *)url error:(NSError **)error NS_AVAILABLE(10_6, 4_0); 根据指定URL打开一份即可读取,又可写入文件内容的文件,并返回该文件对应的NSFileHandle;
7. + (NSFileHandle *)fileHandleWithStandardError; 打开标准错误输出设备对应的NSFileHandle;
8. + (NSFileHandle *)fileHandleWithStandardInput;打开标准输入设备(通常是键盘 )对应的NSFileHandle;
9. + (NSFileHandle *)fileHandleWithStandardOutput;:打开标准输出设备(通常是屏幕 )对应的NSFileHandle;打开标准输入设备(通常是键盘 )对应的NSFileHandle;
10. + (NSFileHandle *)fileHandleWithNullDevice; 打开空设备对应的NSFileHandle;
11. availableData 返回该文件中包含的所有数据;
12. fileDescriptor 获取对应的文件描述器
13. - (NSData *)readDataToEndOfFile; 读取文件中包含的所有数据;
14. - (NSData *)readDataOfLength:(NSUInteger)length; 读取该文件中 length 字节的数据。

- (NSData *)readDataOfLength:(NSUInteger)length; 返回的length 字节的数据包装成 NSData 对象,如果已经超了文件末尾处,程序返回一个不含任何数据的 NSData 对象,SO——程序 可以通过该方法返回的 NSData的length方法是否返回0来判断是否已经读到了文件结尾处。

-
15. - (void)writeData:(NSData *)data; 将指定的 data 数据输入到该文件中;
16. offsetInFile 获取该NSFileHandle中文件指针的位置;
提示:

文件指针记录了当前读,写文件的位置——文件指针所在的位置,也就是接下来 NSFileHandle要读/写的位置。

-
17. - (unsigned long long)seekToEndOfFile; 将该NSFileHandle中文件指针移动到文件的结尾处;
18. - (void)seekToFileOffset:(unsigned long long)offset; 将该NSFileHandle中文件指针移动到指定位置处;
19. - (void)closeFile 关闭底层文件;
20. - (void)truncateFileAtOffset:(unsigned long long)offset 将文件长度截断为 offset 字节——若该offset参数小于文件本身大小,多余的部分被截断;若大于文件本身大小,文件末尾将会被填充空数据;

除此之外,NSFileHandle还提供了用于后台(即异步)读写文件的方法,这些方法大多以InBackgroundAndNotify结尾,这些方法,读,写文件内容时不会阻塞前台线程,会在后台完成对文件的读,写。读,写完成后,这些方法会向前台发一个通知。

特别说明:

NSFileHandle没有创建文件的功能,必须使用 fileManager来 创建对象。
- 当文件不存在时,如果使用fileHandleForWritingAtPathfileHandleForUpdatingAtPath方法来打开文件,这2个方法都会返回 nil;
- 如果文件存在,上面的2个方法打开文件后,文件记录指针都位于文件开始处——即文件记录指针的 offset为0.

示例代码:

#import 

int main(int argc , char * argv[])
{
    @autoreleasepool{
        // 打开一份文件准备读取
        NSFileHandle* fh = [NSFileHandle
            fileHandleForReadingAtPath:@"NSFileHandleTest. m"];
        NSData* data;       
        // 读取NSFileHandle中的256个字节
        while( [(data = [fh readDataOfLength:512]) length] > 0 )
        {
            NSLog(@"%ld" , [data length]);
            // 直接将NSData的数据用UTF-8的格式转换字符串
            NSString* content = [[NSString alloc] initWithData:data 
                encoding:NSUTF8StringEncoding];
            NSLog(@"----------输出读取的512个字节的内容---------");
            NSLog(@"%@" , content);
        }

        // 关闭文件
        [fh closeFile];     
        // 打开一份文件准备写入
        NSFileHandle* fh2 = [NSFileHandle
            fileHandleForWritingAtPath:@"abc. txt"];
        if(!fh2)
        {
            // 创建一个NSFileManager对象
            NSFileManager* fm = [NSFileManager defaultManager];
            // 创建一份空的文件
            [fm createFileAtPath:@"abc. txt"
                contents:nil
                attributes:nil];
            fh2 = [NSFileHandle
                fileHandleForWritingAtPath:@"abc. txt"];
        }
        NSString* myBook = @"疯狂iOS讲义";
        // 将指定内容写入底层文件
        [fh2 writeData:[myBook 
            dataUsingEncoding:NSUTF8StringEncoding]];
        // 关闭文件
        [fh2 closeFile];
    }
}

使用 NSURL 读取网络资源

NSURL:全称Uniform Resource Locator ,统一资源定位符。它是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。[百度百科:URL](http://baike. baidu. com/link?url=hSfNgmXVKOCEQYyHnqU_3wYQp7m97cW4kBFHSRibzy_e5kdyOaj41ngl3HN3OyO7ZhFObPhvl4XBU9zKAcSPZ_)
通常情况下,URL 可以由协议名,主机,端口和资源路径组成:格式如:
scheme://host:port/path ,例如:http://www. baidu. com/index. php 这样的地址。

NSURL 对象的创建,及用法

NSURL 类提供了类方法和初始化方法创建 NSURL 对象,获得NSURL 对象后即可通过程序来获取 NSURL 的各部分内容。多少情况是,程序都会将NSURL 对象作为参数,用于读取网络资源。
示例代码:

#import 

int main(int argc , char * argv[])
{
    @autoreleasepool{
        // 创建NSURL
        NSURL* url = [NSURL
            URLWithString:@"https://www. baidu. com/index. php"];
        NSLog(@"url的scheme为:%@", [url scheme]);
        NSLog(@"url的host为:%@", [url host]);
        NSLog(@"url的port为:%@", [url port]);
        NSLog(@"url的path为:%@", [url path]);
        // 使用URL对应的资源来初始化NSString对象
        NSString* homePage = [NSString stringWithContentsOfURL:
            url encoding: NSUTF8StringEncoding error:nil];
        // 输出NSString内容,即可看到页面源代码
        NSLog(@"%@" , homePage);
    }
}

运行结果:

2015-10-07 17:16:12. 402 1005[1068:14181] url的scheme为:https
2015-10-07 17:16:12. 403 1005[1068:14181] url的host为:www. baidu. com
2015-10-07 17:16:12. 403 1005[1068:14181] url的port为:(null)
2015-10-07 17:16:12. 404 1005[1068:14181] url的path为:/index. php
2015-10-07 17:16:12. 619 1005[1068:14181] <html>
<head>
    <script>        location. replace(location. href. replace("https://","http://"));
    script>
head>
<body>
    <noscript><meta http-equiv="refresh" content="0;url=http://www. baidu. com/">noscript>
body>
html>
2015-10-07 17:16:12. 619 1005[1068:14181] <html>
<head>
    <script>        location. replace(location. href. replace("https://","http://"));
    script>
head>
<body>
    <noscript><meta http-equiv="refresh" content="0;url=http://www. baidu. com/">noscript>
body>
html>

使用 NSBundle处理项目相关资源

NSBundle是个什么鬼?

不管是开发 mac 应用还是 ios 应用,如果应用程序使用绝对路径或者相对路径去访问文件,必然导致程序的可移植性降低。——将我们的应用部署到用户的机器上使用时,对方对应路径下可能根本没有这些文件。

为了提高 mac os 应用或 ios应用的可移植性,我们可以把项目资源文件放在应用中,让应用包含这些资源文件,当包含这些资源文件后,NSBundle就派上用场了,可以使用NSBundle来访问这些应用自包含的资源文件。

NSBundle对象怎么获取?

要获取NSBundle对象,一般会调用该类的 mainBundle 方法,该方法会返回该应用对应的应用程序包。

获取NSBundle对象后,获取指定资源文件的常用方法

  1. 使用类方法创建一个NSBundler对象
    + (NSBundle *)mainBundle;
    eg:[NSBundle mailBundle];
  2. 使用路径获取一个NSBundle 对象,这个路径应该是一个目录的全路径
    + (NSBundle *)bundleWithPath:(NSString *)path;
    eg:
NSString *path = [mailBundle resourcePath];
  NSBundle *language = [NSBundle bundleWithPath:path];

-
3. 使用路径初始化一个NSBundle
- (id)initWithPath:(NSString *)path;
4. 使用一个url 创建并初始化一个NSBundle对象(这是一个类方法)
注:这里的url 是一个特殊的 文件url路径
+ (NSBundle *)bundleWithURL:(NSURL *)url
5. 使用一个url 初始化一个NSBundle对象
注:这里的url 是一个特殊的 文件url路径
- (id)initWithURL:(NSURL *)url
6. 根据一个特殊的class 获取NSBundle
+ (NSBundle *)bundleForClass:(Class)aClass;
eg:根据当前的class 获取一个NSBundle

// 获取当前类的NSBundle
NSBundle *bud = [NSBundle bundleForClass:[self class]];
NSLog(@"bud==%@",bud);
输出结果如下:
NSBundle </Users/ctrip1/Library/Application Support/iPhone Simulator/6. 1/Applications/2F3DA58F-5CF9-48A2-ADB2-C923A29B519E/IOS_Example_NSBundle. app>

-
7. 获取特定名称的bundle
+ (NSBundle *)bundleWithIdentifier:(NSString *)identifier;
8. 使用NSBundle 获取所有的bundle信息(由于ios安全沙盒的限制,所有的获取的资源,是应用程序的资源)
注:官方标注,获取所有的非framework 的bundle;
+ (NSArray *)allBundles;
eg:

NSArray *array = [NSBundle allBundles];
NSLog(@"array===%@",array);
打印的结果如下:
array===(
    "NSBundle  (loaded)"
)

-
9. 获取应用程序加载的所有framework的资源,
+ (NSArray *)allFrameworks;
eg:

NSArray *array = [NSBundle allFrameworks];
NSLog(@"%@",array);

-
10. + (nullable NSURL *)URLForResource: withExtension: subdirectory: inBundleWithUR: NS_AVAILABLE(10_6, 4_0); 根据资源名,扩展名从指定子目录中获取该资源对应的 URL。
11. - (nullable NSURL *)URLForResource:(nullable NSString *)name withExtension:(nullable NSString *)ext NS_AVAILABLE(10_6, 4_0); 根据资源名,扩展名获取该资源对应的 URL。
12. + (nullable NSString *)pathForResource:(nullable NSString *)name ofType:(nullable NSString *)ext inDirectory:(NSString *)bundlePath; 从指定子目录下,根据资源名,类型名获取该资源对应的路径;
13. resourcePath 直接根据完整的资源路径来获取对应的资源。

示例代码段:

// 使用NSBundle获取该应用自包含的指定资源文件的路径
    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"bookinf"
        ofType:@"txt"];
    // 使用指定文件的内容来初始化NSString
    NSString* content = [NSString stringWithContentsOfFile:filePath   encoding:NSUTF8StringEncoding error:nil];
    // 让label显示content字符串的内容
    [label setStringValue: content];

【IOS 开发学习总结-OC-36】★文件 I/O——NSFileHandle&NSURL&NSBundle_第1张图片

你可能感兴趣的:(ios开发)