iOS 各种系统文件目录 临时,缓存,document,lib,归档,序列化

/**
    1:Documents:应用中用户数据可以放在这里,iTunes备份和恢复的时候会包括此目录
    2:tmp:存放临时文件,iTunes不会备份和恢复此目录,此目录下文件可能会在应用退出后删除
    3:Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
     */
    NSArray *paths1=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory
                                                       , NSUserDomainMask
                                                       , YES);
    
    
    NSString *documentsDirect=[paths1 objectAtIndex:0];
    assert(1 == paths1.count);
    NSLog(@">>documentsDirect=%@",documentsDirect);
 
    NSArray *Librarypaths =  NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSDocumentDirectory, YES);
    NSString* libraryDirectory  = [Librarypaths objectAtIndex:0];
    NSLog(@">>Librarypaths.length =%d",[Librarypaths count]);
     assert(1 < Librarypaths.count);
     
    NSLog(@"libraryDirectory=%@",libraryDirectory);
    
    //如果要指定其他文件目录,比如Caches目录,需要更换目录工厂常量,上面代码其他的可不变
    NSArray *pathcaches=NSSearchPathForDirectoriesInDomains(NSCachesDirectory
                                                       , NSUserDomainMask
                                                       , YES);
    NSString* cacheDirectory  = [pathcaches objectAtIndex:0];
    NSLog(@"cacheDirectory=%@",cacheDirectory);
    /**
     使用NSSearchPathForDirectoriesInDomains只能定位Caches目录和Documents目录。
     
     tmp目录,不能按照上面的做法获得目录了,有个函数可以获得应用的根目录
     */
    NSString *tempDir1=NSHomeDirectory() ;
    NSString *tempDir2=NSTemporaryDirectory();
    NSLog(@"tempDir1=%@",tempDir1);
    NSLog(@"tempDir2=%@",tempDir2);

  归档 普通自定义对象和字节流之间的转换

 序列化 某些特定类型(NSDictionary, NSArray, NSString, NSDate, NSNumber,NSData)的数据和字节流之间(通常将其保存为plist文件)的转换

 

 2.1 归档

 如果我们需要将自定义的一个对象保存到文件,应该如何做呢? 

这里引入两个东西:一个是NSCoding协议 ;另一个是NSKeyedArchiver,NSKeyedArchiver其实继承于NSCoder,可以以键值对的方式将对象的属性进行序列化和反序列化。 
具体的过程可以这样描述 通过NSKeyedArchiver 可以将实现了NSCoding协议的对象 和 字节流 相互转换 。

像一些框架中的数据类型如NSDictionary,NSArray,NSString... 都已经实现了NSCoding协议,所以可以直接对他们进行归档操作。

  这里来一个比较完整的例子,一个Address类,一个User类,User类下有个Address类型的属性

#import <Foundation/Foundation.h>

@interface Address : NSObject<NSCoding>
{
    NSString *country;
    NSString *city;
}
@property(nonatomic,copy) NSString *country;
@property(nonatomic,copy) NSString *city; 
@end

 

#import "Address.h"

@implementation Address
@synthesize country;
@synthesize city;
- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:country forKey:@"country"];
    [aCoder encodeObject:city forKey:@"city"];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init]) {
        [self setCountry:[aDecoder decodeObjectForKey:@"country"]];
        [self setCity:[aDecoder decodeObjectForKey:@"city"]];
    } return self;
}
@end

 

#import <Foundation/Foundation.h>
#import "Address.h"
@interface User : NSObject<NSCoding>{
    NSString *_name;
    NSString *_password;
    Address *_address;
}
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *password;
@property(nonatomic,retain) Address *address;

@end

 

#import "User.h"


@implementation User
@synthesize name = _name;
@synthesize password = _password;
@synthesize address = _address;

- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeObject:_password forKey:@"password"];
    [aCoder encodeObject:_address forKey:@"address"];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init]) {
        [self setName:[aDecoder decodeObjectForKey:@"name"]];
        [self setPassword:[aDecoder decodeObjectForKey:@"password"]];
        [self setAddress:[aDecoder decodeObjectForKey:@"address"]];
    }
    return self;
}

@end

 操作应用

 NSString *tempDir2=NSTemporaryDirectory();    
    
    
	// Do any additional setup after loading the view, typically from a nib.
    Address *myAddress = [[Address alloc] init] ;
    myAddress.country = @"中国";
    myAddress.city = @"杭州";
    User *user = [[User alloc] init] ;
    
    user.name = @"卢克";
    user.password = @"lukejin";
    user.address = myAddress;
    //归档  保存的是plist的二进制数据格式
    NSString *path = [tempDir2 stringByAppendingPathComponent:@"user"];
    [NSKeyedArchiver archiveRootObject:user toFile:path];
    
    
    //从文档中读取
    User *object = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    NSLog(@"object.name : %@",object.name);

 

使用数据对象自带的方法,如字典类写文件:

数据:

  NSMutableDictionary *dataDictionary = [[NSMutableDictionary alloc] init] ;
    [dataDictionary setValue:[NSNumber numberWithInt:222] forKey:@"intNumber"];
    [dataDictionary setValue:[NSArray arrayWithObjects:@"1",@"2", nil] forKey:@"testArray"];

 写文件

[dataDictionary writeToFile:@"/Users/zhoumoban/Desktop/test.plist" atomically:YES];

 读文件:

 NSDictionary *dictionaryFromFile = [NSDictionary dictionaryWithContentsOfFile:@"/Users/zhoumoban/Desktop/test.plist"];
    NSLog(@"%@",[dictionaryFromFile objectForKey:@"intNumber"]);

 另外:使用NSPropertyListSerialization类。通过NSPropertyListSerialization类可以将数据对象直接转成NSData或者直接写到文件或者流中去

NSString *error;
    
    NSData *xmlData = [NSPropertyListSerialization dataFromPropertyList:dataDictionary format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
    
    if(xmlData) {
        NSLog(@"No error creating XML data.");
        [xmlData writeToFile:@"/Users/zhoumoban/Desktop/test2.plist" atomically:YES];
    } else {
        if (error) {
            NSLog(@"error:%@", error);
           // [error release];
        }
    }
     //读取
    NSDictionary *dictionaryFromFile2 = (NSDictionary *)[NSPropertyListSerialization propertyListWithData:[NSData dataWithContentsOfFile:@"/Users/zhoumoban/Desktop/test2.plist"] options:0 format:NULL error:&error];
    NSLog(@"===%@",[dictionaryFromFile2 objectForKey:@"intNumber"]);

 

 

猜你喜欢

转载自01jiangwei01.iteye.com/blog/1871685