iOS沙盒与数据的转换与处理

引言:本篇博文主要介绍iOS文件处理,包括NSData,沙盒,常用文件路径,NSBundle的介绍。

1. iOS的沙盒机制

1.1 沙盒

  苹果公司为了限制对应用程序中系统资源和用户数据的访问,以在应用程序受到损害时控制损害,推出了沙盒机制。

  应用程序沙盒通过限制应用程序对通过授权请求的资源的访问,为系统资源和用户数据提供保护。
APP sandbox
再把App SandBox放大:
在这里插入图片描述
  在app被安装后,iOS会为应用创建三个容器,如分别为Bundle Container和Data Container和iCloud Container(接入iCloud,这里不做介绍)。

1.2 Bundle Container

1.2.1 Bundle

  bundle路径就是通常所说的应用程序在手机里面的安装路径,其就是一个目录,这个目录就是main bundle。这个目录里面通常包含图像、媒体资源、编译好的代码、nib、文件等可执行文件和所有资源文件,这个目录是只读的,但是在编程时试试,其实也是可以写入的。

1)怎么打开Bundle目录?
 在Xcode中,找到poducts,其中有一个xxx.app,然后 show in finder。此时有一个xxx.app,然后显示包内容。
 下面是我其中一个demo,有我自己添加的一些资源,具体可以打开自己的某个工程看看。
在这里插入图片描述
2)怎么添加资源文件到Bundle
 一种方法是打开上面的目录,把资源文件放进去,添加目录或者直接放资源都是可以的,
 另外一种方法是,在工程中创建Bundle文件,然后添加资源文件到Bundle。然后获取到天剑的Bundle,然后使用资源文件,

  在代码中我们需要使用NSBundle来读取资源,下面来具体看看代码的使用

1.2.2 使用NSBundle

  用具体代码来使用一下mainBundle。

// 获得主 Bundle 信息
// 就是 .app 目录路径
  NSBundle *mainBundle = [NSBundle mainBundle];
// 获取主Bundle 文件路径
  NSString *bundlePath = [NSBundle mainBundle].bundlePath;
  NSString *resourcePath = [NSBundle mainBundle].resourcePath;
// 获取 Bundle URL 路径
  NSURL *bundleUrl = [NSBundle mainBundle].bundleURL;
  NSURL *resourceURL = [NSBundle mainBundle].resourceURL;
// 获得 Bundle 目录下的文件路径
  NSString *filePath1 = [[NSBundle mainBundle] pathForResource:@"config" ofType:@"json"];
// 获得 bundle 下子目录 subdirectory 下的文件路径
  NSString *filePath2 = [[NSBundle mainBundle] pathForResource:@"config" ofType:@"json" inDirectory:@"configFolder"];
// 获得 Bundle 目录下的 URL 路径
  NSURL *fileUrl1 = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"txt"];
// 获得 bundle 下子目录 subdirectory 下的 URL 路径
  NSURL *fileUrl2 = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"txt" subdirectory:@"testFolder"];

  除了使用资源,我们还可以来使用查询和使用APP的一些信息,这些信息保存在info.plist中。

// 获取应用程序唯一标识包名
  NSString *indentifier = [NSBundle mainBundle].bundleIdentifier;
// 获取应用程序 Info.plist 配置项词典对象实例
  NSDictionary *info = [NSBundle mainBundle].infoDictionary;
// 获取某一特定字段的内容
  NSString *bundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
/*
	其他具体关于info.plist可以在网上在具体了解
*/

  下面来看看怎么创建一个自定义的子Bundle,选择New—>File—>Setting Bundle。最后设置名称,引进资源。
在这里插入图片描述
用代码来使用我们子Bundle。

// 获取某bundle下的某个文件
  NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle  mainBundle] pathForResource:@"xxx" ofType:@"bundle"]];
// 其余和mainBundle的使用方式是一样的
  NSString *path = [bundle pathForResource:@"xxx" ofType:@"plist"];

1.3 Data Container

1.3.1 目录结构

  目录中包含:Documents、Library、tmp

Document : 存储用户数据,需要备份的信息
Library/Caches : 存储缓存文件,程序专用的支持文件
Library/Preferences : 存储应用程序的偏好设置⽂件
tmp : 存储临时文件,比如:下载的zip包,解压后的再删除
注:
iTunes在与iPhone同步时,会备份 DocumentsPreferences 目录下的⽂件 。

  •  Documents:用于存放程序中的文件数据,应用程序在运行时生成的一些需要长久保存的数据(比如:游戏进度存档、应用程序个人设置,下载的资源等等),通过 iTunes、iCloud 备份时, 会备份这个目录下的数据,此目录下保存相对重要的数据。
  •  Library 包含Caches和Preferences⼦目录
     1)Caches:存放缓存文件,从网络上下载的文件或者数据(如:音乐缓存、图片缓存等),此目录下的文件不会在应用退出时自动删除 ,需要程序员手动清除改目录下的数据。iTunes、iCloud 备份时不会备份此目录下的数据。主要用于保存应用在运行时生成的需要长期使用的数据,一般用于存储体积较大,不需要备份的非重要数据。
     2)Preferences存放的是基于NSUserDefaults的设置数据,文件格式为 “plist”。设置应用的一些功能会在该目录中查找相应设置的信息,iTunes、iCloud备份时会备份此目录下的数据。该目录由系统自动管理,通常用来储存一些基本的应用配置信息。比如账号密码、自动登录等。
  •  tmp:存放应用运行时产生的一些临时数据和文件,当应用程序退出、系统磁盘空间不足、手机重启时,都会自动清除该目录的数据。无需程序员手动清除该目录中的数据,iTunes、iCloud备份时不会备份此目录。
1.3.2 使用代码获取目录

NSArray*NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);
用于查找目录,返回指定范围内的指定名称的目录的路径集合。

param:directory 指定收索路径名称,博文后面附上完整的枚举
常用:NSDocumentDirectory、NSLibraryDirectory、NSCachesDirectory
param:domainMask 限定文件检索范围
常用:
NSUserDomainMask = 1,    // 用户主目录
NSLocalDomainMask = 2,    // 当前机器
NSNetworkDomainMask = 4,   // 网络中可见的主机
NSSystemDomainMask = 8,    // 系统目录,不可修改
NSAllDomainsMask = 0x0ffff    // 所有
param:expandTilde        是否显示完整路径,还是使用~相对路径​

// 获取程序的根目录
NSString *homeDirectory = NSHomeDirectory();
// 获取document目录
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// 获取Caches目录
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// 获取Library目录
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
// 获取Tmp目录
NSString *tmpDirectory = NSTemporaryDirectory();

  通常我们都是使用NSFileManager来实现文件IO。这个类后面在数据处理时在详细介绍。

2. 数据的转换与处理

2.1 数据来源

  在数据来源主要是本地文件与网络传输,数据的转换与处理也就是本地文件的数据与网络数据的IO操作,这其中设计数据的转换,由于文件格式,传输便捷等等各种原因,需要对IO数据进行转换与处理,下面就是常见的使用方法。

IO:数据的输入与输出

2.2 NSData

A static byte buffer in memory.

  apple官网上的一句话,就是内存中静态字节缓冲区,在官网中还说明object-oriented wrappers for byte buffers.即就是包装对象。
  NSData屏蔽了数据之间的差异,对象,文本、音频、图像等数据都可用NSData来存储,也常用来数据持久化,网络数据传输等等。神通广大,下面我们来具体使用一下。

    //对象方法创建
    NSData *data1 = [[NSData alloc] init];
    NSData *data2 = [[NSData alloc] initWithData:data1];

    //类方法创建
    NSData *data3 = [NSData data];
    NSData *data4 = [NSData dataWithData:data3];

    //由文件创建
    NSString *filePath = @"xxx/xxx/xxx.xxx";
    NSData *data5 = [[NSData alloc] initWithContentsOfFile:filePath];
    NSData *data6 = [NSData dataWithContentsOfFile:filePath];

    // 由 URL 创建
    NSURL *urlPath = [NSURL URLWithString:@"xxx/xxx"];
    NSData *data7 = [[NSData alloc] initWithContentsOfURL:urlPath];
    NSData *data8 = [NSData dataWithContentsOfURL:urlPath];

    // 由 字符串 创建
    NSString *string = @"hello world!";
    NSData *data9 = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data10 = [string dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

    // 可变 NSData 的创建
    // 初始化时指定对象拥有的字节空间大小,在需要时会增加内存空间,在初始化时并没有分配内存空间
    NSMutableData *data11 = [[NSMutableData alloc] initWithCapacity:5];
    NSMutableData *data12 = [NSMutableData dataWithCapacity:5];

    // 初始化时为对象分配指定长度的归零字节
    NSMutableData *data13 = [[NSMutableData alloc] initWithLength:10];
    NSMutableData *data14 = [NSMutableData dataWithLength:10];

上面是NSData对象的创建,除了NSData对象的转换,还有NSData对象转换成别的对象,因为NSData屏蔽了数据之间的差异,因此常常用来作为两个不同数据的中间对象。

2.3 NSStringPathExtensions

  这是NSString的一个分类,主要是关于文件路径相关的。需要先了解一下。

// 首先我们先假设一个路径。
NSString *filePath = @"/Users/Name/Desktop/file.json";
// 获得组成此路径的各个组成部分,结果:("/","Users","Name","testfile.txt")
 (NSArray *)pathComponents;
// 提取路径的最后一个组成部分,结果:file.json
 (NSString *)lastPathComponent;
// 删除路径的最后一个组成部分,结果:/Users/Name/Desktop
 (NSString *)stringByDeletingLastPathComponent;
// 将path添加到路径的末尾,结果:/Users/Name/Desktop/file.json/Desktop/file.json
// str = @"Desktop/file.json"
 (NSString *)stringByAppendingPathConmponent:(NSString *)str;
// 去路径最后部分的扩展名,结果:json
(NSString *)pathExtension;
// 删除路径最后部分的扩展名,结果:/Users/Name/Desktop/file
 (NSString *)stringByDeletingPathExtension;
// 路径最后部分追加扩展名,不要带. 如.zip .png 不用带前面的点, 直接zip  png
 (NSString *)stringByAppendingPathExtension:(NSString *)str;

2.4 NSFileManager

  NSFileManager是一个单例的文件管理类。通过用defaultManager获取对象;

/* Returns the default singleton instance.
*/
@property (class, readonly, strong) NSFileManager *defaultManager;

下面介绍几个常用的方法。

// 创建一个文件并写入数据
- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr;
// 从一个文件中读取数据
- (NSData *)contentsAtPath:(NSString *)path;
// scrPath路径上的文件移动到dstPath路径上,注意这里的路径是文件路径而不是目录
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **) error;
// scrPath路径上的文件复制到dstPath路径上
- (BOOL)copyItemAtPath:(NSString *)scrPath toPath:(NSString *)dstPath error:(NSError **) error;
// 比较两个文件的内容是否一样
- (BOOL)contentsEqualAtPath:(NSString *)path1 andPath:(NSString *)path2;
// 文件是否存在
- (BOOL)fileExistsAtPath:(NSString *)path;
// 移除文件
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **) error;
// 将NSData对象写入文件
// 从这儿就可以看到,将任何对象转换成NSData对象后,写入文件,都可以实现本地文件持久化
BOOL success = [fileManager createFileAtPath:path contents: NSDataObj attributes:nil];
// NSFileManager-读取内容
NSData *fileData = [fileManager contentsAtPath:filePath];                                   NSString *content = [[NSString alloc] initWithData:fileData dataUsingEncoding: NSUTF8StringEncoding];
// NSData-读取内容
NSString *filePath = [path stringByAppendingPathComponent:@"xxx.txt"];     
NSData *data = [NSData dataWithContentOfFile:filePath];
// NSString-读取内容
NSString *filePath = [path stringByAppendingPathComponent:@"xxx.txt"];     NSString *content = [[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
// 移动、复制、删除文件
// 移动文件(重命名)
BOOL Success = [fileManager moveItemAtPath:filePath toPath:toPath error:nil];
BOOL success = [fileManager copyItemAtPath:filePath toPath:toPath error:nil];
BOOL success = [fileManager removeItemAtPath:filePath error:nil];                                                                                                          
// 获得文件的属性字典
NSDictionary *attrDic = [fileManager attributesOfItemAtpath:sourcePath error:nil];  NSNumber *fileSize = [attrDic objectForKey:NSFileSize];   
// 字典的具体属性见 附

上面这个字典属性,如果没有对Linux文件系统有过了解的话,需要去了解一下,否则不是太容易理解:
【Linux文件与权限】这篇博文简单的理解了Linux下的文件与权限,可以参考一下。

2.5 JSON

  本小姐是关于JSON格式的数据。包括网络传输的数据,本地JSON化的序列数据等,都可以用到。
  我们用到的类是 NSJSONSerialization

我们能利用NSJSONSerialization将JSON转换成Foundation对象,也能将Foundation对象转换成JSON,转换成JSON的对象必须具有如下属性:
1)顶层对象必须是NSArray或者NSDictionary
2)所有的对象必须是NSString、NSNumber、NSArray、NSDictionary、NSNull的实例
3)所有NSDictionary的key必须是NSString类型
4)数字对象不能是非数值或无穷

在我们拿到与JSON格式相关的数据时,可以使用它。通常是网络数据中,response的data数据我们需要对齐进行转换成我们想要的NSDictionary

// 反序列化:根据NSData对象返回一个Foundation对象
+ (id)JSONObjectWithData:(NSData *)data
                 options:(NSJSONReadingOptions)opt
                   error:(NSError **)error
enum {
// 返回可变容器,NSMutableDictionary或NSMutableArray。
   NSJSONReadingMutableContainers = (1UL << 0),
// 返回的JSON对象中字符串的值为NSMutableString,
   NSJSONReadingMutableLeaves = (1UL << 1),
// 返回的既不是字典也不是数组,则必须使用该枚举值
   NSJSONReadingAllowFragments = (1UL << 2)
};
typedef NSUInteger NSJSONReadingOptions;

// 序列化:将foundation对象转换成JSON对象
+ (NSData *)dataWithJSONObject:(id)obj
                       options:(NSJSONWritingOptions)opt
                         error:(NSError **)error

附:

NSSearchPathDirectory

typedef NS_ENUM(NSUInteger, NSSearchPathDirectory) {
    NSApplicationDirectory = 1,             // supported applications (Applications)  应用程序
    NSDemoApplicationDirectory,             // unsupported applications, demonstration versions (Demos)
    NSDeveloperApplicationDirectory,        // developer applications (Developer/Applications). DEPRECATED - there is no one single Developer directory.  已弃用
    NSAdminApplicationDirectory,            // system and network administration applications (Administration)
###Library###
    NSLibraryDirectory,                     // various documentation, support, and configuration files, resources (Library)
    NSDeveloperDirectory,                   // developer resources (Developer) DEPRECATED - there is no one single Developer directory. 已弃用
    NSUserDirectory,                        // user home directories (Users)
    NSDocumentationDirectory,               // documentation (Documentation)
###Document###
    NSDocumentDirectory,                    // documents (Documents)
    NSCoreServiceDirectory,                 // location of CoreServices directory (System/Library/CoreServices)
    NSAutosavedInformationDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 11,   // location of autosaved documents (Documents/Autosaved)
    NSDesktopDirectory = 12,                // location of user's desktop
###Caches###
    NSCachesDirectory = 13,                 // location of discardable cache files (Library/Caches)
    NSApplicationSupportDirectory = 14,     // location of application support files (plug-ins, etc) (Library/Application Support)
    NSDownloadsDirectory API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 15,              // location of the user's "Downloads" directory
    NSInputMethodsDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 16,           // input methods (Library/Input Methods)
    NSMoviesDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 17,                 // location of user's Movies directory (~/Movies)
    NSMusicDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 18,                  // location of user's Music directory (~/Music)
    NSPicturesDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 19,               // location of user's Pictures directory (~/Pictures)
    NSPrinterDescriptionDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 20,     // location of system's PPDs directory (Library/Printers/PPDs)
    NSSharedPublicDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 21,           // location of user's Public sharing directory (~/Public)
    NSPreferencePanesDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 22,        // location of the PreferencePanes directory for use with System Preferences (Library/PreferencePanes)
    NSApplicationScriptsDirectory NS_ENUM_AVAILABLE(10_8, NA) = 23,      // location of the user scripts folder for the calling application (~/Library/Application Scripts/code-signing-id)
    NSItemReplacementDirectory API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 99,        // For use with NSFileManager's URLForDirectory:inDomain:appropriateForURL:create:error:
    NSAllApplicationsDirectory = 100,       // all directories where applications can occur
    NSAllLibrariesDirectory = 101,          // all directories where resources can occur
    NSTrashDirectory API_AVAILABLE(macos(10.8), ios(11.0)) API_UNAVAILABLE(watchos, tvos) = 102             // location of Trash directory
};

文件属性(attributes)

// 文件或者文件夹的大小,注意单位是byte
NSFileSize(不可更改)
// 设置一个表示布尔值的NSNumber对象,表示创建的目录是否是只读的。
NSFileAppendOnly
// 设置一个NSDate对象,表示目录的创建时间。
NSFileCreationDate(可更改时间)
// 设置一个NSString对象,表示这个目录的所有者的名字。
NSFileOwnerAccountName
//设置一个NSString对象,表示这个目录的用户组的名字。
NSFileGroupOwnerAccountName
// 设置一个unsigned int的NSNumber对象,表示目录的组ID。
NSFileGroupOwnerAccountID
// 设置一个NSDate对象,表示目录的修改时间。
NSFileModificationDate(可更改时间)
// 设置一个unsigned int的NSNumber对象,表示目录的所有者ID。
NSFileOwnerAccountID
// 设置一个short int的NSNumber对象,表示目录的访问权限。
NSFilePosixPermissions
// 设置一个unsigned long的NSNumber对象,表示目录的引用计数,即这个目录的硬链接数。
NSFileReferenceCount
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值