IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]OC学习篇之---文件的操作

    jiangwei0910410003发表于 2014-12-13 11:23:25
    love 0

    前一篇文章中我们讲到了OC中的归档和解档操作:http://blog.csdn.net/jiangwei0910410003/article/details/41872551,今天我们来介绍OC中文件操作,在之前的文章中,已经接触到了文件的创建了,但是那不是很具体和详细,这篇文章我们就来仔细看一下OC中是如何操作文件的:


    第一、首先来看一下本身NSString类给我们提供了哪些可以操作文件路径名的方法

    //
    //  main.m
    //  37_FilePathHandle
    //
    //  Created by jiangwei on 14-10-13.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            /演示路径
            NSString *path = @"/Users/jiangwei/file.text";
            
            //1.返回路径的组成部分
            NSArray *array = [path pathComponents];
            NSLog(@"%@",array);
            
            //2.返回路径最后组成部分
            NSString *str = [path lastPathComponent];
            NSLog(@"%@",str);
            
            //3.在原有的路径后面追加子目录
            //这种方式有一点不好,就是需要添加/
            [path stringByAppendingString:@"/appFile.text"];
            //不需要添加/
            [path stringByAppendingPathComponent:@"appFile.text"];
            
            //4.删除最后的组成部分
            str = [path stringByDeletingLastPathComponent];
            //删除扩展名(.text被删除了)
            str = [path stringByDeletingPathExtension];
            
            //5.获取扩展名
            str = [path pathExtension];
            
            //6.添加扩展名
            [path stringByAppendingPathExtension:@".jpg"];
            
        }
        return 0;
    }
    
    在Java中,我们知道,当我们去操作一个文件的时候,最开始的时候肯定要去构建一个路径,这个路径一般都是String类型的,我们需要定义不同的路径和文件名,OC中也不例外,不过OC中的NSString类在这方面做的可能会更好,下面依次来看一下他的方法:

    1、将路径进行分割

    //演示路径
    NSString *path = @"/Users/jiangwei/file.text";
    
    //1.返回路径的组成部分
    NSArray *array = [path pathComponents];
    NSLog(@"%@",array);
    运行结果:


    返回的一个数组,将路径分割了,但是需要注意的是,第一个是"/",这个也算是路径的一部分。


    2、返回路径的最后组成部分

    //2.返回路径最后组成部分
    NSString *str = [path lastPathComponent];
    NSLog(@"%@",str);
    运行结果:


    这个直接返回路径的最后一部分,这个如果放在Java中,我们可能需要用到String类的字符串分割技术了,没有这里的方便


    3、添加子目录/子文件

    //3.在原有的路径后面追加子目录
    //这种方式有一点不好,就是需要添加/
    //演示路径
    str = [path stringByAppendingString:@"/appFile.text"];
    NSLog(@"%@",str);
    //不需要添加/
    str = [path stringByAppendingPathComponent:@"appFile.text"];
    NSLog(@"%@",str);
    这里其实有两种方式可以添加,第一种是直接使用拼接字符串的方式,但是需要手动的添加"/",第二种方式是NSString提供的,不需要手动的添加"/"

    运行结果:



    4、删除最后面的部分和后缀名

    //4.删除最后的组成部分
    str = [path stringByDeletingLastPathComponent];
    NSLog(@"%@",str);
    //删除扩展名(.text被删除了)
    str = [path stringByDeletingPathExtension];
    NSLog(@"%@",str);
    运行结果:



    5、获取扩展名

    //5.获取扩展名
    str = [path pathExtension];
    NSLog(@"%@",str);
    运行结果:



    6、添加扩展名

    //6.添加扩展名
    str = [path stringByAppendingPathExtension:@"jpg"];
    NSLog(@"%@",str);
    运行结果:



    上面就是总结了NSString类中操作文件路径的一些方法,其实这些操作如果放在Java中做的话,就是需要使用String的分割,拼接等技术了。这里看到OC给我们提供了便捷


    第二、在来看一下操作文件之前需要了解的一个对象:NSData

    这个类的作用就是将我们写入到文件中的数据进行编码和解码操作

    //
    //  main.m
    //  38_NSData
    //
    //  Created by jiangwei on 14-10-13.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import Foundation.h>
    
    /NSData类型
    //是一种存储形式
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            //存储是有编码方式的,编程字节码
            //相当于Java中的解码和编码
            NSString *s = @"tsdfsdfsdfsdf";
            NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding];
            s = [[NSString alloc] initWithData:data encoding:(NSUTF8StringEncoding)];
            
            //可变对象 NSMutableData 可以追加数据
        }
        return 0;
    }
    
    这个和Java中String直接在构造的时候就可以进行编码和解码了,这里需要使用中间类NSData,当然这个类是不可变的,如果想追加内容的话,需要使用NSMutableData类


    第三、说完了NSData这个中间类,下面来正式说文件的操作了

    但是这里对文件的操作,我们放到IOS平台去操作,因为我们后面也是会介绍IOS中文件的操作,所以就直接在这里说了,当然这里的知识会有点冲突,但是我们不关心IOS中的其他技术,只看他的文件操作:

    1、沙盒文件

    在IOS中,每个应用程序都是一个沙盒,他们有自己的文件目录,这个目录对其他程序是不可见的,和Android中的/data/data/包名/中的内容差不多,当然IOS中的沙盒目录有三种:

    Documents:存放长期使用的文件(一般存放目录)

    Library:系统存放文件

    tmp:临时文件,app重启时,该目录下得文件清空

    下面来看一个简单的例子吧:

    //
    //  main.m
    //  36_SandBoxFile
    //
    //  Created by jiangwei on 14-10-13.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import UIKit.h>
    #import "AppDelegate.h"
    
    int main(int argc, char * argv[]) {
        @autoreleasepool {
            /获取沙盒目录
            //默认有三个文件夹
            //Documents:存放长期使用的文件(一般存放目录)
            //Library:系统存放文件
            //tmp:临时文件,app重启时,该目录下得文件清空
            
            //第一种获取方式,我们得到Home目录之后,手动的去拼接Document/Library
            NSString *homePath = NSHomeDirectory();
            NSLog(@"沙盒目录:%@",homePath);
            
            //第二种方式,直接使用Api获取
            //NSDocumentDirectory:Documents文件夹
            //NSLibraryDirectory:Library文件夹
            NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
            NSLog(@"%@",array);
            
            NSArray *array1 = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
            NSLog(@"%@",array1);
            
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    
    创建IOS项目和OC差不多:

    后续的操作就一样了,创建完之后的项目结构:


    我们在main.m文件中写我们的代码就可以了。


    下面来看代码:

    //第一种获取方式,我们得到Home目录之后,手动的去拼接Document/Library
    NSString *homePath = NSHomeDirectory();
    NSLog(@"沙盒目录:%@",homePath);
    获取沙盒的home目录,然后我们可以操作在其下面创建子目录了


    这里有两种方式去创建Document等目录,一种是我们用上面NSString类提供的方法去手动拼接目录

    还有一种是用系统给我们提供的方法,这两种都是可以的

    //第二种方式,直接使用Api获取
    //NSDocumentDirectory:Documents文件夹
    //NSLibraryDirectory:Library文件夹
    NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSLog(@"%@",array);
            
    NSArray *array1 = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSLog(@"%@",array1);

    看一下运行结果:




    第四、了解了程序的沙盒目录,下面继续来看一下操作文件的两个类

    一、NSFileManager

    这个类的主要功能是对文件进行操作:创建,复制,剪切,删除等

    看代码:

    //
    //  main.m
    //  39_NSFileManager
    //
    //  Created by jiangwei on 14-10-13.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import UIKit.h>
    #import "AppDelegate.h"
    
    /NSFileManager:对文件进行操作的,包括复制,粘贴,删除,剪切等操作
    int main(int argc, char * argv[]) {
        @autoreleasepool {
            
            //------------------创建文件/文件夹
            //获取沙盒目录
            NSString *homePath = NSHomeDirectory();
            //在沙盒目录中创建一个文件file.text
            NSString *filePath = [homePath stringByAppendingPathComponent:@"Documents/file.text"];
            //NSFileManager是单利模式,所以不能使用alloc+init创建
            NSFileManager *manager = [NSFileManager defaultManager];
            NSString *str = @"无线互联";
            NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
            //参数:文件路径、文件内容、文件的属性
            BOOL sucess = [manager createFileAtPath:filePath contents:data attributes:nil];
            if(sucess){
                NSLog(@"文件创建成功");
            }else{
                NSLog(@"文件创建失败");
            }
            
            //创建文件夹
            NSString *filePaths = [homePath stringByAppendingPathComponent:@"Documents/file"];
            NSError *error;
            //需要传递一个创建失败的指针对象,记录创建失败的信息
            BOOL success1 = [manager createDirectoryAtPath:filePaths withIntermediateDirectories:YES attributes:nil error:&error;];
            if(!success1){
                NSLog(@"创建成功");
            }else{
                NSLog(@"创建失败");
            }
            
            
            //--------------------读取文件
            //根据路径读取文件内容
            NSData *datas = [manager contentsAtPath:filePath];
            NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"%@",s);
            
            
            //--------------------移动文件/剪切文件
            //NSFileManager中没有提供重命名的方法,所以我们可以借助移动的api进行操作
            //把filePath移动到targetPath目录中
            NSString *targetPath = [homePath stringByAppendingPathComponent:@"Documents/file/file2.text"];
            BOOL sucess2 = [manager moveItemAtPath:filePath toPath:targetPath error:nil];
            if(sucess2) {
                NSLog(@"移动成功");
            }else{
                NSLog(@"移动失败");
            }
            
            
            //--------------------复制文件
            BOOL sucess3 = [manager copyItemAtPath:filePath toPath:targetPath error:nil];
            if(sucess3){
                //复制成功
            }else{
                //复制失败
            }
            
            
            //--------------------删除文件
            //删除之前需要判断这个文件是否存在
            BOOL isExist = [manager fileExistsAtPath:filePath];//判断文件是否存在
            if(isExist){
                BOOL sucess4 = [manager removeItemAtPath:filePath error:nil];
                if(sucess4){
                    //删除成功
                }else{
                    //删除失败
                }
            }
            
            
            //--------------------获取文件的属性
            NSDictionary *dic = [manager attributesOfItemAtPath:filePath error:nil];
            NSLog(@"%@",dic);//通过打印我们就可以查看文件属性的一些key
            
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    


    1、创建文件

    //------------------创建文件/文件夹
    //获取沙盒目录
    NSString *homePath = NSHomeDirectory();
    //在沙盒目录中创建一个文件file.text
    NSString *filePath = [homePath stringByAppendingPathComponent:@"Documents/file.text"];
    //NSFileManager是单利模式,所以不能使用alloc+init创建
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *str = @"无线互联";
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    //参数:文件路径、文件内容、文件的属性
    BOOL sucess = [manager createFileAtPath:filePath contents:data attributes:nil];
    if(sucess){
        NSLog(@"文件创建成功");
    }else{
        NSLog(@"文件创建失败");
    }
    NSFileManager内部使用了单例模式,这个后面会说到OC中得单例模式,然后就是构建一个NSData类,最后使用createFileAtPath方法创建文件,不过最后的attributes参数一般是用来给这个文件定义一些属性的,当然文件本身也是有很多默认的属性,比如文件的大小,文件的创建日期等,我们也可以自己在追加一些属性。


    2、创建文件夹

    //创建文件夹
    NSString *filePaths = [homePath stringByAppendingPathComponent:@"Documents/file"];
    NSError *error;
    //需要传递一个创建失败的指针对象,记录创建失败的信息
    BOOL success1 = [manager createDirectoryAtPath:filePaths withIntermediateDirectories:YES attributes:nil error:&error;];
    if(!success1){
        NSLog(@"创建成功");
    }else{
        NSLog(@"创建失败");
    }
    从这两个操作看出来,他和Java中的File类很相似的


    3、读取文件

    //--------------------读取文件
    //根据路径读取文件内容
    NSData *datas = [manager contentsAtPath:filePath];
    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@",s);


    4、剪切文件

    //--------------------移动文件/剪切文件
    //NSFileManager中没有提供重命名的方法,所以我们可以借助移动的api进行操作
    //把filePath移动到targetPath目录中
    NSString *targetPath = [homePath stringByAppendingPathComponent:@"Documents/file/file2.text"];
    BOOL sucess2 = [manager moveItemAtPath:filePath toPath:targetPath error:nil];
    if(sucess2) {
        NSLog(@"移动成功");
    }else{
        NSLog(@"移动失败");
    }
    这里有两个参数:一个是需要移动文件的路径,和需要移动到哪的路径


    5、复制文件

    //--------------------复制文件
    BOOL sucess3 = [manager copyItemAtPath:filePath toPath:targetPath error:nil];
    if(sucess3){
        //复制成功
    }else{
        //复制失败
    }

    6、删除文件

    //--------------------删除文件
    //删除之前需要判断这个文件是否存在
    BOOL isExist = [manager fileExistsAtPath:filePath];//判断文件是否存在
    if(isExist){
        BOOL sucess4 = [manager removeItemAtPath:filePath error:nil];
        if(sucess4){
            //删除成功
        }else{
            //删除失败
        }
    }

    7、操作文件的属性
    //--------------------获取文件的属性
    NSDictionary *dic = [manager attributesOfItemAtPath:filePath error:nil];
    NSLog(@"%@",dic);//通过打印我们就可以查看文件属性的一些key
    属性一般是NSDictionary


    二、NSFileHandle

    这个类主要是对文件进行读写操作的

    看代码:

    //
    //  main.m
    //  40_NSFileHandle
    //
    //  Created by jiangwei on 14-10-13.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import UIKit.h>
    #import "AppDelegate.h"
    
    /写文件,我们之前使用各种数据结构来存储数据:NSString,NSData,NSDictionary,NSArray等,他们都是有一个writeToFile方法用来写文件的
    
    //纯文本:没有任何格式的数据
    //非纯文本:有修饰的数据(字体大小,字体颜色等)
    
    //数组只能将如下类型写入文件,如果包含其他对象,将写入失败:NSNumber,NSString,NSData,NSDate,NSArray,NSDictionary
    //数组、字典写入的文件叫做属性文件,可以使用xcode进行编辑
    int main(int argc, char * argv[]) {
        @autoreleasepool {
            
            //1.-------------------字符串读写文件
            NSString *str = @"无线互联";
            NSString *homePath = NSHomeDirectory();
            NSString *filePath = [homePath stringByAppendingPathComponent:@"Documents/file.text"];
            //现在有这样的场景,第一次把字符串写入到文件中,当我们修改字符串之后,再次写入的时候,但是可能会写入失败
            //但是之前的内容也有可能丢失,因为每次在写入新的内容的时候,会剪切之前的内容,所以这里就有可能新的没有写
            //成功,旧的文件也丢失了
            //所以这时候atomically参数:
            //YES:会将新内容先写入到一个缓存文件中,如果写入缓存成功之后,这时候就将这个缓存文件替换旧文件,这样就很安全了
            BOOL sucess = [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
            if(sucess){
                //写入成功
            }else{
                //写入失败
            }
            //读取文件内容到字符串中
            //类方法
            NSString *str1 = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
            //构造方法
            //str1 = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
            NSLog(@"%@",str1);
            
            
            //2.--------------------NSData读写
            //创建NSData的同时读取文件中的内容
            NSData *data = [[NSData alloc] initWithContentsOfFile:filePath];
            //NSData转化成NSString
            NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"%@",s);
            
            //写文件
            BOOL sucess1 = [data writeToFile:filePath atomically:YES];
            if(sucess1){
                //写入成功
            }else{
                //写入失败
            }
            
            
            //3.--------------------NSArray读写文件
            NSArray *array = @[@"zhangsan",@"lisi"];
            //属性文件一般后缀名为.plist
            NSString *filePaths = [homePath stringByAppendingPathComponent:@"Documents/array.plist"];
            BOOL sucess2 = [array writeToFile:filePaths atomically:YES];
            if(sucess2){
                //写入成功
            }else{
                //写入失败
            }
            //读文件
            NSArray *arrays = [[NSArray alloc] initWithContentsOfFile:filePath];
            NSLog(@"%@",arrays);
            
            
            //4.---------------------NSDictionary读写文件
            NSDictionary *dic = @{@"zhang":@"zhangsan",@"li":@"lisi"};
            BOOL sucess3 = [dic writeToFile:filePath atomically:YES];
            if(sucess3){
                //写入成功
            }else{
                //写入失败
            }
            
            //读文件
            dic = [[NSDictionary alloc] initWithContentsOfFile:filePath];
            NSLog(@"%@",dic);
            
            
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    
    这个类就和Java中的FileInputStream/FileOutputStream类似了

    其实我们在之前看到归档和解档操作的时候,那就是相当于写文件和读文件操作了。


    1、字符串直接写入文件

    //1.-------------------字符串读写文件
    NSString *str = @"无线互联";
    NSString *homePath = NSHomeDirectory();
    NSString *filePath = [homePath stringByAppendingPathComponent:@"Documents/file.text"];
    //现在有这样的场景,第一次把字符串写入到文件中,当我们修改字符串之后,再次写入的时候,但是可能会写入失败
    //但是之前的内容也有可能丢失,因为每次在写入新的内容的时候,会剪切之前的内容,所以这里就有可能新的没有写
    //成功,旧的文件也丢失了
    //所以这时候atomically参数:
    //YES:会将新内容先写入到一个缓存文件中,如果写入缓存成功之后,这时候就将这个缓存文件替换旧文件,这样就很安全了
    BOOL sucess = [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
    if(sucess){
        //写入成功
    }else{
        //写入失败
    }
    //读取文件内容到字符串中
    //类方法
    NSString *str1 = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    //构造方法
    //str1 = [[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"%@",str1);
    
    我们使用拼接的方式创建Documents目录中的file.text文件,然后将字符串内容写入到其中。

    writeToFile方法进行写入

    其实OC中的各种数据结构都有这个方法的:NSString,NSData,NSArray,NSSet,NSDirctionary等

    这里有两点要注意的:

    1)

    数组只能将如下类型写入文件,如果包含其他对象,将写入失败:NSNumber,NSString,NSData,NSDate,NSArray,NSDictionary

    数组、字典写入的文件叫做属性文件,可以使用xcode进行编辑


    这个就是系统提供的一个属性文件:info.plist

    这个和Java中的Property文件很类似


    2)writeToFile方法的第一个参数:automically

    现在有这样的场景,第一次把字符串写入到文件中,当我们修改字符串之后,再次写入的时候,但是可能会写入失败但是之前的内容也有可能丢失,因为每次在写入新的内容的时候,会剪切之前的内容,所以这里就有可能新的没有写成功,旧的文件也丢失了所以这时候atomically参数:YES:会将新内容先写入到一个缓存文件中,如果写入缓存成功之后,这时候就将这个缓存文件替换旧文件,这样就很安全了


    2、NSData的内容读写

    //2.--------------------NSData读写
    //创建NSData的同时读取文件中的内容
    NSData *data = [[NSData alloc] initWithContentsOfFile:filePath];
    //NSData转化成NSString
    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"%@",s);
    
    //写文件
    BOOL sucess1 = [data writeToFile:filePath atomically:YES];
    if(sucess1){
        //写入成功
    }else{
        //写入失败
    }


    3、NSArray的内容读写

    //3.--------------------NSArray读写文件
    NSArray *array = @[@"zhangsan",@"lisi"];
    //属性文件一般后缀名为.plist
    NSString *filePaths = [homePath stringByAppendingPathComponent:@"Documents/array.plist"];
    BOOL sucess2 = [array writeToFile:filePaths atomically:YES];
    if(sucess2){
        //写入成功
    }else{
        //写入失败
    }
    //读文件
    NSArray *arrays = [[NSArray alloc] initWithContentsOfFile:filePath];
    NSLog(@"%@",arrays);


    4、NSDirctionary的内容读写

    //4.---------------------NSDictionary读写文件
    NSDictionary *dic = @{@"zhang":@"zhangsan",@"li":@"lisi"};
    BOOL sucess3 = [dic writeToFile:filePath atomically:YES];
    if(sucess3){
        //写入成功
    }else{
        //写入失败
    }
    
    //读文件
    dic = [[NSDictionary alloc] initWithContentsOfFile:filePath];
    NSLog(@"%@",dic);
    上面说到的系统的info.plist文件就是NSDirctionary

    三、在来看一下NSFileHandle的其他用法

    //
    //  main.m
    //  41_NSFileHandleTest
    //
    //  Created by jiangwei on 14-10-14.
    //  Copyright (c) 2014年 jiangwei. All rights reserved.
    //
    
    #import UIKit.h>
    #import "AppDelegate.h"
    
    /NSFileHandle是对文件内容进行读写
    int main(int argc, char * argv[]) {
        @autoreleasepool {
            
            //追加数据
            NSString *str = @"无线互联";
            NSString *homePath = NSHomeDirectory();
            NSString *filePath = [homePath stringByAppendingPathComponent:@"file.test"];
            [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];//写入文件
            
            NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:filePath];
            //默认是从开始位置写,所以我们需要将写入游标设置到尾部
            //从文件的末尾写入
            [handle seekToEndOfFile];
            NSString *s = @"123";
            NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding];
            [handle writeData:data];
            //关闭文件
            [handle closeFile];
            
            
            //读取文件
            NSFileHandle *handles = [NSFileHandle fileHandleForReadingAtPath:filePath];
            
            //获取文件的大小
            NSFileManager *fileManager = [NSFileManager defaultManager];
            NSDictionary *fileAttr = [fileManager attributesOfItemAtPath:filePath error:nil];
            NSNumber *fileSize = [fileAttr objectForKey:NSFileSize];
            long long sizeValue = [fileSize longLongValue];
            
            //设置偏移量
            [handle seekToFileOffset:sizeValue/2];//将偏移量设置到中间位置
            //从当前偏移量读到文件末尾
            NSData *datas = [handle readDataToEndOfFile];
            NSString *s2 = [[NSString alloc] initWithData:datas encoding:NSUTF8StringEncoding];
            NSLog(@"%@",s2);
            
            //一个汉字占用两个字节,有时候可能会将一个汉字分成两半,有乱码的问题,需要注意
            
            
            //实现复制文件的功能
            //使用NSFileHandle只能读写已经存在的文件,不能创建文件,创建文件应该使用NSFileManager
            NSString *targetPath = [homePath stringByAppendingPathComponent:@"files.test"];
            NSFileManager *fileManagers = [NSFileManager defaultManager];
            [fileManagers createFileAtPath:targetPath contents:nil attributes:nil];
            
            //创建读取文件的handle
            NSFileHandle *readHandles = [NSFileHandle fileHandleForReadingAtPath:filePath];
            //创建写文件的handle
            NSFileHandle *writeHandles = [NSFileHandle fileHandleForWritingAtPath:targetPath];
            
            //从当前偏移量读取到文件的末尾
            NSData *datass = [readHandles readDataToEndOfFile];
            //还有一种方式读取文件,既可以读取文件,也可以读流,功能更强
            //[readHandles availableData];
            [writeHandles writeData:datass];
            
            //关闭文件
            [readHandles closeFile];
            [writeHandles closeFile];
            
            //这里有问题,就是读取文件的时候全部读取了,这样会很占内存的,所以我们应该将读取内容进行分段
            
            
            
                                   
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    


    1、对原有的内容进行追加操作

    //追加数据
    NSString *str = @"无线互联";
    NSString *homePath = NSHomeDirectory();
    NSString *filePath = [homePath stringByAppendingPathComponent:@"file.test"];
    [str writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:nil];//写入文件
    
    NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:filePath];
    //默认是从开始位置写,所以我们需要将写入游标设置到尾部
    //从文件的末尾写入
    [handle seekToEndOfFile];
    NSString *s = @"123";
    NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding];
    [handle writeData:data];
    //关闭文件
    [handle closeFile];
    记得操作完之后,关闭文件,我们在追加文件的时候,只要在将当前游标移动到文件的末尾处即可,默认是在开始处


    2、读取文件的任何位置内容

    //读取文件
    NSFileHandle *handles = [NSFileHandle fileHandleForReadingAtPath:filePath];
    
    //获取文件的大小
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSDictionary *fileAttr = [fileManager attributesOfItemAtPath:filePath error:nil];
    NSNumber *fileSize = [fileAttr objectForKey:NSFileSize];
    long long sizeValue = [fileSize longLongValue];
    
    //设置偏移量
    [handle seekToFileOffset:sizeValue/2];//将偏移量设置到中间位置
    //从当前偏移量读到文件末尾
    NSData *datas = [handle readDataToEndOfFile];
    NSString *s2 = [[NSString alloc] initWithData:datas encoding:NSUTF8StringEncoding];
    NSLog(@"%@",s2);
    还是设置一下游标的位置即可


    3、实现文件的复制功能

    //实现复制文件的功能
    //使用NSFileHandle只能读写已经存在的文件,不能创建文件,创建文件应该使用NSFileManager
    NSString *targetPath = [homePath stringByAppendingPathComponent:@"files.test"];
    NSFileManager *fileManagers = [NSFileManager defaultManager];
    [fileManagers createFileAtPath:targetPath contents:nil attributes:nil];
    
    //创建读取文件的handle
    NSFileHandle *readHandles = [NSFileHandle fileHandleForReadingAtPath:filePath];
    //创建写文件的handle
    NSFileHandle *writeHandles = [NSFileHandle fileHandleForWritingAtPath:targetPath];
    
    //从当前偏移量读取到文件的末尾
    NSData *datass = [readHandles readDataToEndOfFile];
    //还有一种方式读取文件,既可以读取文件,也可以读流,功能更强
    //[readHandles availableData];
    [writeHandles writeData:datass];
    
    //关闭文件
    [readHandles closeFile];
    [writeHandles closeFile];
    
    //这里有问题,就是读取文件的时候全部读取了,这样会很占内存的,所以我们应该将读取内容进行分段
    这里的这种方式是:直接将源文件内容全部读取出来,然后写入到目标文件中,这样做有一个坏处,如果这个文件的内容太大,那么一次读取出那么多内容,内存会爆的,所以应该采用分段读取,这个就用到了上面说到的读取文件的任意位置的内容


    总结

    这一篇主要是介绍了文件的操作,对于文件的操作,后面的IOS开发过程中会经常用到,所以也是一个重点,当然还有一点需要说明的是,OC中的文件操作比Java中的文件操作方便多了。


















沪ICP备19023445号-2号
友情链接