IOS中的沙盒机制(SandBox)是一种安全体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如图片、声音、属性列表和文本文件等。
1.每个应用程序都在自己的沙盒内
2.不能随意跨越自己的沙盒去访问别的应用程序沙盒的内容
3.应用程序向外请求或接收数据都需要经过权限认证
查看模拟器的沙盒文件夹在Mac电脑上的存储位置,首先,这个文件夹是被隐藏的,所以要先将这些文件显示出来,打开命令行:
显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true
隐藏Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool false
然后重新启动Finder,点击屏幕左上角苹果标志——强制退出——选择Finder然后点击重新启动,这个时候在重新打开Finder就可以看到被隐藏的文件了。
还有一种比较简单的办法就是:
直接点击Finder图标右键——前往文件夹——输入:
/Users/本机用户名/Library/Developer/CoreSimulator/Devices/189C28D8-F8BF-4280-9301-9BC5A18F45D5/data/Containers/Data/Application/F3BAF1C5-7ECB-41AC-B07F-6C44F6248798/
然后确认就可以了(如果系统更新的话可能会有变化?反正现在是这样的)。
模拟器的沙盒文件目录了:
接着进入一个模拟器文件夹
然后可以看到Applications下面存放的就是模拟器中所装的开发的应用程序,随便进入一个后可以看到沙盒内的具体内容,如图所示:
真实iPhone设备同步时,iTunes会备份Documents和Library目录下的文件。当iPhone重启时,会丢弃所有的tmp文件。
下面的说法是从其他博客看来的:
- Documents,苹果建议将程序中创建的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录;
- Library,存储程序的默认设置或其它 状态信息;
- tmp,创建和存放临时文件的地 方。
下面通过代码来获取这些目录:
//获取根目录
NSString *homePath = NSHomeDirectory();
NSLog(@"Home目录:%@",homePath);
//获取Documents文件夹目录
//第一个参数是说明获取Doucments文件夹目录
//第二个参数说明是在当前应用沙盒中获取,所有应用沙盒目录组成一个数组结构的数据存放
NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [docPath objectAtIndex:0];
NSLog(@"Documents目录:%@",documentsPath);
一般情况下,获取Documents路径不是最终目的,如果试图获取Documents目录下的某个文件的路径,则需要调用stringByAppendingPathComponent方法,例如,获取Documents目录下的Test目录再下面的image.png图片路径的方法:
//现获取Documents路径
NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [docPath objectAtIndex:0];
//再获取后面的东西
NSString *filePath = [docPath strstringByAppendingPathComponentn:@"Test/image.png"];
//获取Cache目录
NSArray *cacPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [cacPath objectAtIndex:0];
NSLog(@"Cache目录:%@",cachePath);
//Library目录
NSArray *libsPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libPath = [libsPath objectAtIndex:0];
NSLog(@"Library目录:%@",libPath);
//temp目录
NSString *tempPath = NSTemporaryDirectory();
NSLog(@"temp目录:%@",tempPath);
下面开始向目录里面创建文件,然后向文件里面写入内容:
NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [docPath objectAtIndex:0];
//写入文件
if (!documentsPath)
{
NSLog(@"目录未找到");
}
else
{
NSString *filePaht = [documentsPath stringByAppendingPathComponent:@"test.txt"];
NSArray *array = [NSArray arrayWithObjects:@"Title",@"Contents", nil];
[array writeToFile:filePaht atomically:YES];
}
创建成功后打开文件夹目录,可以看到test.txt文件:
接下来是把该文件中的内容读出来:
//读取文件
NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [docPath objectAtIndex:0];
NSString *readPath = [documentsPath stringByAppendingPathComponent:@"test.txt"];
NSArray *fileContent = [[NSArray alloc] initWithContentsOfFile:readPath];
NSLog(@"文件内容:%@",fileContent);
下面写的是我自己写在Util里面的一些文件操作有关的方法:
//这里是定义的一个枚举
typedef NS_ENUM(NSUInteger, DirectoryInSandBox) {
DirectoryInSandBoxCache,
DirectoryInSandBoxDocument,
};
获取绝对路径
//获取文件或目录fileName在Cache文件夹中的绝对路径
+ (NSString *)pathInCacheDirectory:(NSString *)fileName
{
NSArray *cachePaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [cachePaths objectAtIndex:0];
return [cachePath stringByAppendingPathComponent:fileName];
}
//获取文件或目录fileName在Document文件夹中的绝对路径
+ (NSString *)pathInDocDirectory:(NSString *)fileName
{
NSArray *cachePaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *cachePath = [cachePaths objectAtIndex:0];
return [cachePath stringByAppendingPathComponent:fileName];
}
创建新文件夹
//创建新文件夹
+ (BOOL)createDir:(NSString *)dirName inDir:(DirectoryInSandBox)whichInSandbox
{
//获取新文件夹dirName的绝对路径
NSString *newDirPath = nil;
switch (whichInSandbox) {
case DirectoryInSandBoxCache:
{
newDirPath = [self pathInCacheDirectory:dirName];
}
break;
case DirectoryInSandBoxDocument:
{
newDirPath = [self pathInDocDirectory:dirName];
}
break;
default:
break;
}
BOOL isDir = NO;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL existed = [fileManager fileExistsAtPath:newDirPath isDirectory:&isDir];
bool isCreated = false;
//如果不存在路径newDirPath,或路径newDirPath代表的不是一个目录,则新建目录
if ( !(isDir == YES && existed == YES) )
{
isCreated = [fileManager createDirectoryAtPath:newDirPath withIntermediateDirectories:YES attributes:nil error:nil];
}
return isCreated;
}
//在Cache文件夹中创建新文件夹
+ (BOOL)createDirInCache:(NSString *)dirName
{
return [self createDir:dirName inDir:DirectoryInSandBoxCache];
}
//在Document文件夹中创建新文件夹
+ (BOOL)createDirInDocument:(NSString *)dirName
{
return [self createDir:dirName inDir:DirectoryInSandBoxDocument];
}
删除文件夹
// 删除文件夹
+ (bool) deleteDir:(NSString *)dirName inDir:(DirectoryInSandBox)whichInSandbox
{
//获取要删除文件夹dirName的绝对路径
NSString *deleteDirPath = nil;
switch (whichInSandbox) {
case DirectoryInSandBoxCache:
{
deleteDirPath = [self pathInCacheDirectory:dirName];
}
break;
case DirectoryInSandBoxDocument:
{
deleteDirPath = [self pathInDocDirectory:dirName];
}
break;
default:
break;
}
BOOL isDir = NO;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL existed = [fileManager fileExistsAtPath:deleteDirPath isDirectory:&isDir];
bool isDeleted = false;
// 当路径存在并且是表示目录,则删除
if ( isDir == YES && existed == YES )
{
isDeleted = [fileManager removeItemAtPath:deleteDirPath error:nil];
}
return isDeleted;
}
// 删除Cache文件夹中的文件夹
+ (bool) deleteDirInCache:(NSString *)dirName
{
return [self deleteDir:dirName inDir:DirectoryInSandBoxCache];
}
// 删除Document文件夹中的文件夹
+ (bool) deleteDirInDocument:(NSString *)dirName
{
return [self deleteDir:dirName inDir:DirectoryInSandBoxDocument];
}
图片保存,从其他人博客里面看过来的,没用过
//将图片保存到Cache目录
+ (BOOL)saveImageToCacheDir:(NSString *)directoryPath image:(UIImage *)image imgName:(NSString *)imageName imgType:(NSString *)imageType
{
BOOL isDir = NO;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL existed = [fileManager fileExistsAtPath:directoryPath isDirectory:&isDir];
bool isSaved = false;
//如果路径存在并且表示目录,则依据不同图片类型保存
if ( isDir == YES && existed == YES )
{
if ([[imageType lowercaseString] isEqualToString:@"png"])
{
isSaved = [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil];
}
else if ([[imageType lowercaseString] isEqualToString:@"jpg"] || [[imageType lowercaseString] isEqualToString:@"jpeg"])
{
isSaved = [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil];
}
else
{
NSLog(@"Image Save Failed\nExtension: (%@) is not recognized, use (PNG/JPG)", imageType);
}
}
return isSaved;
}
//从Cache文件夹中加载图片到imageView中
+ (NSData *)loadImageData:(NSString *)directoryPath imgName:(NSString *)imageName
{
BOOL isDir = NO;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL dirExisted = [fileManager fileExistsAtPath:directoryPath isDirectory:&isDir];
//路径存在并且表示目录时,判断目录中是否有图片名对应的图片
if ( isDir == YES && dirExisted == YES )
{
NSString *imagePath = [directoryPath stringByAppendingString : imageName];
BOOL fileExisted = [fileManager fileExistsAtPath:imagePath];
if (!fileExisted) {
return NULL;
}
NSData *imageData = [NSData dataWithContentsOfFile:imagePath];
return imageData;
}
else
{
return NULL;
}
}