iOS沙盒机制和文件操作



 沙盒就是应用程序的安装过程中、系统为每个单独的应用程序生成它的主目录和一些关键的子目录  — 文件夹。


  沙盒机制是一种安全体系,它规定了应用程序只能在本应用程序沙盒中读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如图片、音频、视频、属性列表(偏好设置)和文本文件等。

优点 安全 每个应用程序都在自己的沙盒内 不能随意跨越自己的沙盒区访问别的应用程序沙盒的内容,应用程序向外请求或接受数据都需要经过权限认证

缺点 文件访问受限 访问文件不灵活


    每个iOS应用都被限制在“沙盒”中,“沙盒”相当于一个加了仅主人可见权限的文件夹,苹果对沙盒有以下几条限制。

    (1)、应用程序可以在自己的沙盒里运作,但是不能访问任何其他应用程序的沙盒。

    (2)、应用程序间不能共享数据,沙盒里的文件不能被复制到其他应用程序文件夹中,也不能把其他应用程序文件夹中的文件复制到沙盒里。

    (3)、苹果禁止任何读、写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中。

如何找到Sandbox路径?

点击屏幕—菜单栏显示Finder——前往(按住option键)—资源库—Application support——iPhone simulator——7.1——Applications 下存放的是应用程序对应的沙盒;


绝对路径:

/Users/Camille/Library/Application Support/iPhone Simulator/7.1/Applications/3B41BD98-C84D-4C82-84C1-D602CFF55475/Documents

相对路径:  ~当前域

~/Library/Application Support/iPhone Simulator/7.1/Applications/3B41BD98-C84D-4C82-84C1-D602CFF55475/Documents



应用程序在运行时,会随机生成一个32位 数字加字母的字符串


目录结构

1.xxxx.app


目录包含了应用程序本身的数据,包括资源文件和可执行文件等。程序启动以后,会根据需要从该目录中动态加载代码或资源到内存,这里用到了lazy loading的思想。

②整个目录是只读的

为了防止被篡改,应用在安装的时候会将该目录签名。非越狱情况下,该目录中内容是无法更改的;在越狱设备上如果更改了目录内容,对应的签名就会被改变,这种情况下苹果官网描述的后果是应用程序将无法启动


2、Documents


我们可以将应用程序的数据文件保存在该目录下。不过这些数据类型仅限于不可再生的数据,可再生的数据文件应该存放在Library/Cache目录下。例如,游戏应用可将游戏存档保存在该Documents目录 


3、Documents/Inbox(了解)


保存应⽤用运⾏行时⽣生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应⽤用可将游戏存档保存在该⽬录 ;该目录还是用来保存由外部应用请求当前应用程序打开的文件。

比如我们的应用叫A,向系统注册了几种可打开的文件格式,B应用有一个A支持的格式文件F,并且申请调用A打开F。由于F当前是在B应用的沙盒中,我们知道,沙盒机制是不允许A访问B沙盒中的文件,因此苹果的解决方案是将F拷贝一份到A应用的Documents/Inbox目录下,再让A打开F。


4、Library   苹果建议用来存放默认设置或其它状态信息。


5、Library/Caches   主要是缓存文件,用户使用过程中缓存都可以保存在这个目录中。保存应⽤运行时⽣成的需要持久化的数据,iTunes同步设备时不会备份该⽬目录。一般存储体积⼤大、不需要备份的⾮重要数据 


6、Library/Preferences  保存应⽤用的所有偏好设置。我们使用NSUserDefaults写的设置数据也会保存到该目录下的一个plist文件中!


7、tmp  保存应⽤运⾏时所需的临时数据,使用完毕后再将相应的文件从该⽬目录删除。应⽤没有运⾏时,该目录下的东西随时有可能被系统清理掉,例如:系统磁盘存储空间不足的时候。iPhone在重启时,会丢弃所有的tmp文件。



数组的存取


一)写入到指定的目录

1)第一种方法

   

 NSArray* array = [[NSArray alloc] initWithObjects:@"读",@"写",@"读和写",@"只读",@"读写", nil];
     NSString* sandBoxPath = NSHomeDirectory();
     NSString* path = [sandBoxPath stringByAppendingPathComponent:@"Documents/54"];


2)第二种方法


  

 NSArray* array = [[NSArray alloc] initWithObjects:@"读",@"写",@"读和写",@"只读",@"读写", nil];
   NSString* documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
   NSString* path = [documentPath stringByAppendingPathComponent:@"54"];

二)取数据


   

 NSArray* readArray1 = [[NSArray alloc] initWithContentsOfFile:filePath];
     NSArray* readArray2 = [NSArray arrayWithContentsOfFile:filePath];



注意:数组中的元素有中文时,打印的结果是编码后的内容,可以使用for循环打印


   

   for (id object in readArray1) 
    {

        NSLog(@"____%@",object);
    }



把获取指定目录的文件设置成一个方法直接调用


获取指定目录下的文件

<pre name="code" class="objc">- (NSString *)getFilePath:(NSString *)fileName
{
    NSString* filePath = [[self getDocumentPath] stringByAppendingPathComponent:fileName];
    return 
}


 ilePath; 

Documents目录路径

- (NSString *)getDocumentPath
{
    NSString* documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    return documentPath;
}




 

    

注意:writeToFile:写入数据时,多次写入会将之前的内容覆盖掉

    

字典的写入

   

 NSDictionary* dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"11",@"1",@"22",@"2",@"33",@"3", nil];
     NSDictionary* dic = @{@"1": @"11",@"2":@"22",@"3":@"33"};
     NSString* filePath2 = [self getFilePath:@"2"];
     [dictionary writeToFile:filePath2 atomically:YES];

    

读取

   

 NSDictionary* readDic1 = [[NSDictionary alloc] initWithContentsOfFile:filePath2];
     NSDictionary* readDic2 = [NSDictionary dictionaryWithContentsOfFile:filePath2];
     NSLog(@"2____%@___%@",readDic1,readDic2);

    

    

字符串的写入

    

    

NSString* string = @"字符串的读取";
     NSString* filePath3 = [self getFilePath:@"33"];
	[string writeToFile:filePath3 atomically:YES encoding:NSUTF8StringEncoding error:nil];
 encoding:使用哪种编码格式:UIFT-8    将字符串编码成data
 error:存储时的错误信息:nil


    

读取

   

 NSString* readString1 = [[NSString alloc] initWithContentsOfFile:filePath3 encoding:NSUTF8StringEncoding error:nil];
    NSString* readString2 = [NSString stringWithContentsOfFile:filePath3 encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"3____%@___%@",readString1,readString2);
    

    

    

    

 NSData 写入

    

NSString* dataStr = @“123。。。”;
    //NSString-->NSData
    NSData* data = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
    NSString* filePath4 = [self getFilePath:@"datafile"];
    [data writeToFile:filePath4 atomically:YES];

    

    

读取:

    

NSData* readData = [[NSData alloc] initWithContentsOfFile:filePath4];
    NSData* readData2 = [NSData dataWithContentsOfFile:filePath4];
    NSLog(@"___%@___%@",readData,readData2);
    
    [self.window makeKeyAndVisible];
    return YES;
}


获取指定目录下的文件

- (NSString *)getFilePath:(NSString *)fileName
{
    NSString* filePath = [[self getDocumentPath] stringByAppendingPathComponent:fileName];
    return filePath;
}





获取应用沙盒根路径:

-(void)dirHome{  
    NSString *dirHome=NSHomeDirectory();      
    NSLog(@"app_home: %@",dirHome);  
}

  


获取Documents目录路径:

(1)拼接:拼接时系统会自动添加一个‘/’;拼接的方式,易出错

    

NSString* documentPath = [homePath stringByAppendingPathComponent:@"Documents"];
     NSLog(@"2.1Document路径——————%@",documentPath);

(2)字符串拼接:

    

NSString* document2 = [NSString stringWithFormat:@"%@/Documents",homePath];
     NSLog(@"2.2____%@",document2);

    

(3)采用搜索路径:根据指定区域搜索指定文件夹

    1.要搜索的文件夹(目录):Document

    2.要搜索的区域:NSUserDomainMask当前域(当前根目录及沙盒目录)

    3.是否获取全路径(完整路径):使用绝对路径或者相对路径

    方法返回值为数组,此数组中第一个路径是要获取的正确路径

   

 NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,        NSUserDomainMask, YES);
     NSString* document3 = paths[0];
     NSLog(@"2.3____%@",document3); 

获取Library目录路径:





  1. 获取Library目录    

-(void)dirLib{  
    //[NSHomeDirectory() stringByAppendingPathComponent:@"Library"];  
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);  
    NSString *libraryDirectory = [paths objectAtIndex:0];  
    NSLog(@"app_home_lib: %@",libraryDirectory);  
}


获取 Cache 目录路径:





  1. 获取Cache目录    

-(void)dirCache{  
    NSArray *cacPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);  
    NSString *cachePath = [cacPath objectAtIndex:0];  
    NSLog(@"app_home_lib_cache: %@",cachePath);  
}


获取Tmp目录路径:






  1. //获取Tmp目录   

-(void)dirTmp{  
    //[NSHomeDirectory() stringByAppendingPathComponent:@"tmp"];  
    NSString *tmpDirectory = NSTemporaryDirectory();  
    NSLog(@"app_home_tmp: %@",tmpDirectory);  
} 



创建文件夹:




  1. //创建文件夹    

-(void *)createDir{  
    NSString *documentsPath =[self dirDoc];  
    NSFileManager *fileManager = [NSFileManager defaultManager];  
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
    // 创建目录  
    BOOL res=[fileManager createDirectoryAtPath:testDirectory withIntermediateDirectories:YES attributes:nil error:nil];  
    if (res) {  
        NSLog(@"文件夹创建成功");  
    }else  
        NSLog(@"文件夹创建失败");  
 }




创建文件




  1. //创建文件  

-(void *)createFile{  
    NSString *documentsPath =[self dirDoc];  
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
    NSFileManager *fileManager = [NSFileManager defaultManager];  
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];  
    BOOL res=[fileManager createFileAtPath:testPath contents:nil attributes:nil];  
    if (res) {  
        NSLog(@"文件创建成功: %@" ,testPath);  
    }else  
        NSLog(@"文件创建失败");  
}  


写数据到文件:





  1. //写文件   

-(void)writeFile{  
    NSString *documentsPath =[self dirDoc];  
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];  
    NSString *content=@"测试写入内容!";  
    BOOL res=[content writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:nil];  
    if (res) {  
        NSLog(@"文件写入成功");  
    }else  
        NSLog(@"文件写入失败");  
} 


读文件数据:





  1. //读文件  

-(void)readFile{  
    NSString *documentsPath =[self dirDoc];  
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];  
//    NSData *data = [NSData dataWithContentsOfFile:testPath];  
//    NSLog(@"文件读取成功: %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);  
    NSString *content=[NSString stringWithContentsOfFile:testPath encoding:NSUTF8StringEncoding error:nil];  
    NSLog(@"文件读取成功: %@",content);  
}  


文件属性:





  1. //文件属性    

-(void)fileAttriutes{  
    NSString *documentsPath =[self dirDoc];  
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
    NSFileManager *fileManager = [NSFileManager defaultManager];  
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];  
    NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:testPath error:nil];     
    NSArray *keys;  
    id key, value;  
    keys = [fileAttributes allKeys];  
    int count = [keys count];  
    for (int i = 0; i < count; i++)  
    {  
        key = [keys objectAtIndex: i];  
        value = [fileAttributes objectForKey: key];  
        NSLog (@"Key: %@ for value: %@", key, value);  
    }  
}



删除文件:

  


  1. //删除文件  
-(void)deleteFile{  
    NSString *documentsPath =[self dirDoc];  
    NSString *testDirectory = [documentsPath stringByAppendingPathComponent:@"test"];  
    NSFileManager *fileManager = [NSFileManager defaultManager];  
    NSString *testPath = [testDirectory stringByAppendingPathComponent:@"test.txt"];     
    BOOL res=[fileManager removeItemAtPath:testPath error:nil];  
    if (res) {  
        NSLog(@"文件删除成功");  
    }else  
        NSLog(@"文件删除失败");     
    NSLog(@"文件是否存在: %@",[fileManager isExecutableFileAtPath:testPath]?@"YES":@"NO");  
}  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS 上,应用的沙盒目录是私有的,其他应用无法直接访问。因此,要从 JS 中获取 iOS 沙盒内的文件,需要通过 Native Bridge 的方式,即将 JS 中的请求传递给原生代码,由原生代码来实现文件读取并返回结果给 JS。 以下是一个简单的示例,假设你要获取沙盒内的一个名为 `example.txt` 的文件: 1. 在原生代码中实现文件读取逻辑,例如使用 `NSFileManager` 类读取文件内容: ```objc - (NSString *)readFileContentsAtPath:(NSString *)path { NSFileManager *fileManager = [NSFileManager defaultManager]; NSData *data = [fileManager contentsAtPath:path]; return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } ``` 2. 在 JS 中定义一个函数,用于调用原生代码并获取文件内容: ```js function getExampleFileContents() { // 调用 Native Bridge 方法,传递路径参数 const path = 'path/to/example.txt'; const contents = NativeBridge.readFileContentsAtPath(path); return contents; } ``` 3. 在原生代码中实现 Native Bridge 方法,并将其暴露给 JS 环境: ```objc - (void)registerNativeBridgeMethods { [self.bridge registerNativeMethod:@"readFileContentsAtPath" handler:^(NSString *path) { NSString *contents = [self readFileContentsAtPath:path]; // 将结果返回给 JS 环境 [self.bridge callHandler:@"onFileContentsReceived" withArguments:@[contents]]; }]; } ``` 4. 在 JS 中注册 `onFileContentsReceived` 回调函数,用于接收原生代码返回的文件内容: ```js function onFileContentsReceived(contents) { // 处理文件内容 console.log(contents); } NativeBridge.registerEventHandler('onFileContentsReceived', onFileContentsReceived); ``` 注意:以上示例仅为演示 Native Bridge 的基本用法,具体实现方式可能因框架、平台、业务需求等因素而异。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值