iOS为每个应用提供了独立的文件空间,一个应用只能直接访问本应用分配的文件目录,不可以访问其他目录,每个应用自己独立的访问空间被称为该应用的沙盒。
一、 沙盒
在app被安装时,iOS会为应用创建三个容器,如
分别为Bundle Container和Data Container和iCloud Container。
iOS 8.0 之后,bundle 目录和沙盒目录 (Data) 是分开的。iOS 7.0 及以前版本 bundle 目录和沙盒目录 (Data) 是在一起的。
1. Bundle Container
MyApp.app :这就是应用的运行包(bundle),
bundle路径就是通常所说的应用程序在手机里面的安装路径,其就是一个目录,这个目录就是main bundle。这个目录里面通常包含图像、媒体资源、编译好的代码、nib、文件等可执行文件和所有资源文件,这个目录是只读的。
// 获得 Bundle 信息
/*
通常指向 xxx.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:@"test" ofType:@"txt"];
// 获得 bundle 下子目录 subdirectory 下的文件路径
NSString *filePath2 = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"txt" inDirectory:@"testFolder"];
// 获得 Bundle 目录下的 URL 路径
NSURL *fileUrl1 = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"txt"];
// 获得 bundle 下子目录 subdirectory 下的 URL 路径
NSURL *fileUrl2 = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"txt" subdirectory:@"testFolder"];
// 获取应用程序唯一标识包名
NSString *indentifier = [NSBundle mainBundle].bundleIdentifier;
// 获取应用程序 Info.plist 配置项词典对象实例
NSDictionary *info = [NSBundle mainBundle].infoDictionary;
// 获取某一特定字段的内容
NSString *bundleID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
// 获取某bundle下的某个文件
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"bundle"]];
NSString *path = [bundle pathForResource:@"xxx" ofType:@"plist"];
2. Data Container
获取主目录路径
NSString * homePath = NSHomeDirectory();
可分为三个部分,Documents、Library、tmp。
如下图所示
2.1 Document
保存由用户产生的文件或者数据,苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录,该文件夹下的内容不会被系统自动删除,例如:例如一个日记应用中用户写的日记文件,或者音乐播放器中用户下载的歌曲。
// 获取 Document 路径
NSString * documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,
TRUE).firstObject;
2.2 Library
// 获取 Library 路径
NSString *libraryPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
NSUserDomainMask,
TRUE)
.firstObject;
2.2.1 Library/Caches
用来存放缓存文件,保存从网络下载的请求数据,后续仍然需要继续使用的文件,例如网络下载的离线数据,图片,视频文件等。该目录中的文件系统不会自动删除,可以做离线访问。它的存放时间比 tmp 下的长,但是不如 Library 下的其它目录。总的来说 Caches 目录下存放的数据不能是应用程序运行所必需的,但是能提高应用访问性能的。可写入应用支持文件,保存应用程序再次启动需要的信息。iCloud不备份。
// 获取 Caches 路径
NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask,
TRUE)
.firstObject;
2.2.2 Library/Preferences
常用来放置配置文件、数据文件、模板等应用在运行中与用户相关,而又希望对用户不可见的文件,如系统偏好设置,用户偏好设置等文件。使用 NSUserDefaults 类进行偏好设置文件的创建、读取和修改。
2.3 temp
保存应用运行时产生的一些临时数据,应用程序退出,系统磁盘空间不够,手机重启时,都会自动清除该目录的数据。无需程序员手动清除该目录中的数据.iTunes、iCloud备份时,不会备份此目录
//获取临时文件路径
NSString *tempPath = NSTemporaryDirectory();
2.4 文件路径
// 获取满足条件的路径列表
NSArray<NSString *> * NSSearchPathForDirectoriesInDomains(
NSSearchPathDirectory directory,
NSSearchPathDomainMask domainMask,
BOOL expandTilde);
- 参数: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
};
- NSSearchPathDomainMask 指定查找的文件系统域,可以是多值
typedef NS_OPTIONS(NSUInteger, NSSearchPathDomainMask) {
###UserDomain###
NSUserDomainMask = 1, // user's home directory --- place to install user's personal items (~) 当前用户的 home 目录
NSLocalDomainMask = 2, // local to the current machine --- place to install items available to everyone on this machine (/Library) //指向对所有用户可用的当前机器范围
NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network)
NSSystemDomainMask = 8, // provided by Apple, unmodifiable (/System)
NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items
};
- expandTilde :指定是否展开路径中的代字符“~”,YES代表展开
数据存储
write to file 思路:先得到目录路径,然后write to file
1.基本数据类型,字符串、字典、数组等
比如我们在Document目录进行存储
- (NSString *)getDocumentFilePath
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString * documentDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, TRUE)[0];
if (![fileManager fileExistsAtPath:documentDir]) {
[fileManager createDirectoryAtPath:documentDir withIntermediateDirectories:YES attributes:nil error:nil];
}
return documentDir;
}
//获取document目录路径
NSString *documentPath = [self getDocumentFilePath];
//创建一个test.txt路径
NSString *testPath = [documentPath stringByAppendingPathComponent:@"test.txt"];
NSString *content = @"这仅仅是测试";
NSError * error;
[content writeToFile:testPath atomically:TRUE encoding:NSUTF8StringEncoding error:&error];
if (!error) {
NSLog(@"写入数据成功");
}else{
NSLog(@"写入数据失败");
}
/*
NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding];
BOOL success = [data writeToFile:testPath atomically:TRUE];
if (success) {
NSLog(@"写入数据成功");
}else{
NSLog(@"写入数据失败");
}
*/
读取数据
//获取document目录路径
NSString *documentPath = [self getDocumentFilePath];
//创建一个test.txt路径
NSString *testPath = [documentPath stringByAppendingPathComponent:@"test.txt"];
NSString *str = [[NSString alloc]initWithContentsOfFile:testPath encoding:NSUTF8StringEncoding error:nil];
// NSData *data = [NSData dataWithContentsOfFile:testPath];
// NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",str);
//存字典
NSDictionary *dict = @{@"key":@"这仅仅是测试"};
BOOL success = [dict writeToFile:testPath atomically:TRUE];
//读字典
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:testPath];
- 自定义类的对象
保存自定义的类对象,需要用到NSKeydeArchiver归档。必须使被归档的类遵守NSCoding协议并且实现协议方法。
下面以例子来说明
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@end
Person.m
#import "Person.h"
@implementation Person
// 当一个对象要保存到文件中的时候回调用如下方法,所以重写该方法,说明保存该对象的时候要保存哪些属性。
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
// 当一个对象从文件中读取的时候,系统会调用该方法,重写该方法
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
if ([super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntForKey:@"age"];
}
return self;
}
@end
Person *p = [[Person alloc] init];
p.name = @"joe";
p.age = 20;
//获取文件路径
NSString *docPath=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString *path=[docPath stringByAppendingPathComponent:@"person.txt"];
//将自定义的对象保存到文件中
[NSKeyedArchiver archiveRootObject:p1 toFile:path];
//读取数据
Person *person =[NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSUserDefaults
使用NSUserDefaults来保存数据, 会将所有的数据都保存到Preferences的文件夹下的同一个plist文件中。保存格式为plist文件格式。
使用偏好设置对数据进行保存, 它保存的时间是不确定的,会在将来某一时间自动将数据保存到Preferences文件夹下,如果需要即刻将数据存储,使用[defaults synchronize]。
// 获取NSUserDefaults对象
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 保存数据
[defaults setObject:@"这仅仅是测试" forKey:@"key"];
// 让数据立刻保存
[defaults synchronize];
//读取数据
NSString *test = [defaults objectForKey:@"test"];
如下图所示
SQLite
采用 SQLite 数据库来存储数据。SQLite 作为一中小型数据库,通常用来存储大量数据。但是进行操作时需要使用C语言的函数,比较麻烦。
FMDB是对SQLite3框架封装以OC的方式进行操作的第三方框架,相对于原生SQLite,使用起来更加方便,而且对于多线程的并发操作进行了处理,是线程安全的。
在项目中导入FMDB文件github地址或者pod 'FMDB'
然后导入libsqlite3.0框架
和导入FMDB.h
下面我们以一个例子来说明
创建一个Student类和一个Cource类
@interface Student : NSObject<NSCoding>
@property (nonatomic, assign) NSInteger sId;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSArray *courses;
@end
@interface Course : NSObject<NSCoding>
@property (nonatomic, strong) NSString *name;
@end
因为Student类里包含自定义对象,所以存储时需要遵循NSCoding协议进行归档操作
@implementation student
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.sId = [aDecoder decodeIntForKey:@"sId"];
self.name = [aDecoder decodeObjectForKey:@"name"];
self.courses = [aDecoder decodeObjectForKey:@"cources"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeInteger:self.sId forKey:@"sId"];
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.courses forKey:@"cources"];
}
@end
@implementation Course
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
}
@end
数据库操作
//建数据库,建表
FMDatabase *fmdb;
NSString *_dbPath;
- (void)initDataBase{
//获得documents目录路径
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//文件路径
_dbPath = [documentPath stringByAppendingPathComponent:@"student.db"];
//示例化FMDataBase对象
NSLog(@"-----path:%@",_dbPath);
fmdb = [FMDatabase databaseWithPath:_dbPath];
if ([fmdb open]) {
//初始化数据表
[self addStudentTable];
}else{
NSLog(@"数据库打开失败---%@",fmdb.lastErrorMessage);
}
}
//创建Student表格
- (void)addStudentTable{
NSString *studentSql = @"create table if not exists student (id integer Primary Key Autoincrement, sId integer, name text, courses blob)";
BOOL studentSuccess = [fmdb executeUpdate:studentSql];
if (!studentSuccess) {
NSLog(@"student表格创建失败---%@", fmdb.lastErrorMessage);
}else{
NSLog(@"student表格创建成功");
}
}
//text 数据库中文本数据,blob 数据库中用来存储二进制文件的字段类型
查
//获取student表格全部数据
- (NSMutableArray *)getAllStudent{
NSMutableArray * students = [[NSMutableArray alloc]init];
if ([fmdb open]) {
//查找student所有列表,按照id升序
/*
desc是descend 降序意思
asc 是ascend 升序意思 默认
*/
FMResultSet *result = [fmdb executeQuery:@"select * from student order by id desc"];
while ([result next]) {
Student *student = [[Student alloc] init];
student.sId = [[result stringForColumn:@"sId"] integerValue];
student.name = [result stringForColumn:@"name"];
student.courses = [self unarchivedObjectWithObject:data];
[students addObject:student];
}
[fmdb close];
}
return students;
}
//根据学生id查找student信息
- (Student *)searchStudent:(NSString *)sId{
if ([fmdb open]) {
//通过名字查询学生信息
NSString*sql = [NSString stringWithFormat:@"select * from student where sId = %ld ", sId.integerValue];
FMResultSet *result = [fmdb executeQuery:sql];
while ([result next]) {
Student*student = [[Student alloc] init];
student.sId= [result intForColumn:@"sId"];
student.name= [result stringForColumn:@"name"];
student.courses = [self unarchivedObjectWithObject:data];
[fmdb close];
return student;
}
}
return nil;
}
//归档
- (id)archivedObjectWithObject:(id)object
{
if (object == nil || object == [NSNull null]) {
return nil;
}
return [NSKeyedArchiver archivedDataWithRootObject:object];
}
//解档
- (id)unarchivedObjectWithObject:(id)object
{
if (object == nil || object == [NSNull null]) {
return nil;
}
return [NSKeyedUnarchiver unarchiveObjectWithData:object];
}
增
//student表格添加内容
- (void)addStudent:(Student *)student{
if ([fmdb open]) {
NSString*sql =@"insert into student(sId,name,courses) values(?,?,?)";
BOOL isAddSuccess = [fmdb executeUpdate:sql,@(student.sId),student.name,[self archivedObjectWithObject:student.courses]];
if (!isAddSuccess) {
NSLog(@"student表格插入信息失败---%@",fmdb.lastErrorMessage);
}else{
NSLog(@"student表格插入信息成功!");
}
[fmdb close];
}
}
删
//student表删除内容
- (void)deleteStudent:(Student *)student{
if ([fmdb open]) {
NSString *sql = @"delete from student where sId = ?";
BOOL isDeleteSuccess = [fmdb executeUpdate:sql,@(student.sId)];
if (!isDeleteSuccess) {
NSLog(@"student表格删除信息失败---%@",fmdb.lastErrorMessage);
}else{
NSLog(@"student表格删除信息成功!");
}
}
}
//删除student表
- (void)deleteAllStudent{
if ([fmdb open]) {
NSString *sql = @"delete from student";
BOOL isSuccess = [fmdb executeUpdate:sql];
if (!isSuccess) {
NSLog(@"student表格全部删除失败--%@",fmdb.lastErrorMessage);
}else{
NSLog(@"student表格全部删除成功! ");
}
[fmdb close];
}
}
改
//student表修改内容
- (void)updateStudent:(Student *)student{
if ([fmdb open]) {
NSString*SQL =@"update student set name = ?, cources = ? where sId = ?";
BOOL isSuccess = [fmdb executeUpdate: SQL, student.name,[self archivedObjectWithObject:student.courses]];
if(!isSuccess) {
NSLog(@"student修改失败--%@",fmdb.lastErrorMessage);
}else{
NSLog(@"student修改失败");
}
[fmdb close];
}
}
项目中如果使用了多线程操作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。不可在多个线程中共同使用一个FMDatabase对象操作数据库,这样会引起数据库数据混乱。为了多线程操作数据库安全,FMDB使用了FMDatabaseQueue,首先用一个数据库文件地址来初使化FMDatabaseQueue,然后就可以将一个闭包(block)传入inDatabase方法中。 在闭包中操作数据库,而不直接参与FMDatabase的管理。
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:_dbPath];
再来看看查找所有Student
//获取student表格全部数据
- (NSMutableArray *)getAllStudent{
NSMutableArray * students = [[NSMutableArray alloc]init];
[queue inDatabase:^(FMDatabase * _Nonnull db) {
if ([fmdb open]) {
//查找student所有列表,按照id升序
/*
desc是descend 降序意思
asc 是ascend 升序意思 默认
*/
FMResultSet *result = [fmdb executeQuery:@"select * from student order by id desc"];
while ([result next]) {
Student *student = [[Student alloc] init];
student.sId = [[result stringForColumn:@"sId"] integerValue];
student.name = [result stringForColumn:@"name"];
student.courses = [self unarchivedObjectWithObject:data];
[students addObject:student];
}
[fmdb close];
}
}];
return students;
}
结合GCD队列
- (void)addStudents:(NSArray *)students{
for (int i = 0; i < students.count ;i ++) {
const char *queueName = [[NSString stringWithFormat:@"queque%d",i] UTF8String];
dispatch_queue_t q = dispatch_queue_create(queueName, NULL);
dispatch_async(q, ^{
[queue inDatabase:^(FMDatabase * _Nonnull db) {
Student *student = students[i];
NSString *sql = @"insert into student (sId, name, cources) values (?,?,?)";
BOOL isSuccess = [db executeUpdate:sql, @(student.sId),student.name,[self archivedObjectWithObject:student.courses]];
if(!isSuccess) {
NSLog(@"studentTable插入信息失败--%@",db.lastErrorMessage);
}else{
NSLog(@"studentTable插入信息成功!");
}
}];
});
}
}
三、文件管理
管理存储在沙盒中的文件,这时候需要用到NSFileManager了,
NSFileManager是iOS中的文件管理类。
NSFileManager *manger = [NSFileManager defaultManager];
判断文件获取目录是否存在
NSString *documentPath = [self getDocumentFilePath];
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test.txt"];
BOOL isExit1 = [manger fileExistsAtPath:filePath];
// isExit1为YES,说明test.txt这个文件是存在的
BOOL isDirectory;
BOOL isExit2 = [manger fileExistsAtPath:filePath isDirectory:&isDirectory];
// isExit2为YES,说明test.txt这个文件是存在的;
isDirectory为NO,说明这个path是文件,而不是目录,当isDirectory为YES时,说明这个path是目录
创建目录或者文件
NSString *filePath = [documentPath stringByAppendingPathComponent:@"ceshi"];
NSError *error;
[manger createDirectoryAtPath:filePath withIntermediateDirectories:FALSE attributes:nil error:&error];
if (error) {
NSLog(@"创建文件夹错误, error:%@",[error localizedDescription]);
}else{
NSLog(@"创建文件夹成功");
}
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test1.txt"];
NSData *data = [@"这也是一个测试" dataUsingEncoding:NSUTF8StringEncoding];
[manger createFileAtPath:filePath contents:data attributes:nil];
然后我们看看沙盒里,果然是多了一个ceshi目录和test1.txt
删除文件
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test1.txt"];
NSError *error;
[manger removeItemAtPath:filePath error:&error];
获取文件信息
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test.txt"];
NSFileManager *manger = [NSFileManager defaultManager];
NSError *error;
NSDictionary *dict = [manger attributesOfItemAtPath:filePath error:&error];
NSLog(@"%@",dict);
打印:
{
NSFileCreationDate = "2017-08-14 10:40:14 +0000";
NSFileExtendedAttributes = {
"com.apple.TextEncoding" = <7574662d 383b3133 34323137 393834>;
};
NSFileExtensionHidden = 0;
NSFileGroupOwnerAccountID = 20;
NSFileGroupOwnerAccountName = staff;
NSFileModificationDate = "2017-08-14 10:40:14 +0000";
NSFileOwnerAccountID = 501;
NSFilePosixPermissions = 420;
NSFileReferenceCount = 1;
NSFileSize = 18;
NSFileSystemFileNumber = 59320208;
NSFileSystemNumber = 16777220;
NSFileType = NSFileTypeRegular;
}
NSFileSize(不可更改)
文件或者文件夹的大小,注意单位是byte
NSFileAppendOnly
这个键的值需要设置为一个表示布尔值的NSNumber对象,表示创建的目录是否是只读的。
NSFileCreationDate(可更改时间)
这个键的值需要设置为一个NSDate对象,表示目录的创建时间。
NSFileOwnerAccountName
这个键的值需要设置为一个NSString对象,表示这个目录的所有者的名字。
NSFileGroupOwnerAccountName
这个键的值需要设置为一个NSString对象,表示这个目录的用户组的名字。
NSFileGroupOwnerAccountID
这个键的值需要设置为一个表示unsigned int的NSNumber对象,表示目录的组ID。
NSFileModificationDate(可更改时间)
这个键的值需要设置一个NSDate对象,表示目录的修改时间。
NSFileOwnerAccountID
这个键的值需要设置为一个表示unsigned int的NSNumber对象,表示目录的所有者ID。
NSFilePosixPermissions
这个键的值需要设置为一个表示short int的NSNumber对象,表示目录的访问权限。
NSFileReferenceCount
这个键的值需要设置为一个表示unsigned long的NSNumber对象,表示目录的引用计数,即这个目录的硬链接数