iOS:文件操作相关(18-03-23更)

0、iOS文件系统

1、工程内文件

2、文件夹管理

3、文件操作

4、NSCache

 

附录:

1、沙盒文件夹、文件大小

2、清除沙盒 Library / Cache 下所有数据

3、测试plist

 

 

 

0、写在前面

  1、文件名不能有“/”,“/”代表下一级目录。如要做文件缓存:

    1)、要么,把文件名(网络地址),“/”替换成如“_”,[fileUrl stringByReplacingOccurrencesOfString:@"/" withString:@"_"] 。

    2)、要么,MD5编码,换新名。

  2、contentsOfDirectoryAtPath:只获取该目录下的 根文件夹、根文件。

    subpathsAtPath:遍历出该目录下所有的 子文件夹、子文件。

 

==================== iOS文件系统 ====================

Document:一般需要持久的数据都放在此目录中。用户操作生成的数据。(iTunes备份和恢复)

Library:设置程序的默认设置和其他状态信息。网络下载的数据。(iTunes备份和恢复,除了 Library / Cache )

  Library / Preferences : 偏好设置(最好不要动,NSUserDefaults 的 plist 文件保存在这个目录下,只能存一份,会覆盖)

  Library / Cache : 缓存,不会备份

tmp:创建临时文件的目录,当iOS设备重启时,文件会被自动清除

补充:数据只能保存在上面3个文件夹里,否则无法写入,同时,乱写入到不对应的文件夹,也有可能上架不了。

 

0、直接获取

// 获取 根目录 路径
NSString *userRootPath = NSHomeDirectory();
// 获取 tmp 路径
NSString *userTmpPath = NSTemporaryDirectory();

1、拼接写法

#define kDocumentsPath          [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
#define kLibraryPath            [NSHomeDirectory() stringByAppendingPathComponent:@"Library"]
#define kLibrary_Caches_Path    [kLibraryPath stringByAppendingPathComponent:@"Caches"]

  补充:字符串形式,容易写错、或者修改到。

2、搜索写法

// 参数1:
// NSDocumentDirectory  : 获取 Documents 路径
// NSLibraryDirectory   : 获取 Library 路径
// NSCachesDirectory    : 获取 Library / cache 路径
// 参数:
// NSUserDomainMask     : 只在 user 里搜索
// 参数3:
// YES                  : YES,根目录显示出来,NO,根目录为"~"
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) firstObject];

  补充:有 firstObject 写法,也有 lastObject 写法。反推过去,理论上,返回的数组只有一个对象。

 

==================== 工程内文件 ====================

0、工程路径

[[NSBundle mainBundle] bundlePath];

1、获取文件路径

NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"apple" ofType:@"png"];
NSString *voicePath = [[NSBundle mainBundle] pathForResource:@"apple" ofType:@"wav"];

2、获取文件

UIImage*appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];

  音频参照“iOS:小技巧” -> “7、播放音频” -> “2)工程内音频”

 

==================== 文件夹管理 ====================

0、写在前面。创建、或删除等等操作,看需求先判断是否存在,再操作。

//判断文件夹、文件是否存在
[fileManager fileExistsAtPath:oldPath]

1、拿到文件管理者单例

NSFileManager *fileManager = [NSFileManager defaultManager];

2、使用管理者创建文件夹

//path:要创建的文件夹名,文件夹名是没有后缀的
[fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]

3、创建文件(plist文件,直接用数组、字典自带的write方法)

//filePath:在之前文件夹下创建的文件,为“xxx.xxx”    data要编码
[fileManager createFileAtPath:filePath contents:data attributes:nil]

4、读取文件信息

//返回字典
[fileManager attributesOfItemAtPath:filePath error:&error]

5、读取文件返回的字典信息

[infoDic objectForKey:@"NSFileSize"]

6、文件读取

6-1)、方法1:

//读到NSData
NSData *newData = [fileManager contentsAtPath:filePath];
//解码
[[NSString alloc]initWithData:newData encoding:NSUTF8StringEncoding];

6-2)、方法2:

[[NSString alloc]initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];

7、文件移动(剪切、重命名)

//文件名有后缀”xxx.xx”
[fileManager moveItemAtPath:oldPath toPath:newPath error:&error]

8、文件复制

//文件名有后缀“xxx.xx”
[fileManager copyItemAtPath:oldPath toPath:newPath error:&error]

9、文件删除

//文件名有后缀“xxx.xx”
[fileManager removeItemAtPath:oldPath error:&error]

  

==================== 文件操作 ====================

1、写入

1-1)、设置为写入模式

NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:path];

1-2)、先转码

NSString *newString = @"hello,hello,hello,世界";
NSData *newData = [new_string dataUsingEncoding:NSUTF8StringEncoding];

1-3)、再写入

[fileHandle writeData:newData];

1-4)、追加

//先找到最后的
[fileHandle seekToEndOfFile];

//写入转码后的数据
[fileHandle writeData:newData2];

1-5)、覆盖(如需插入操作,1、全读取,2、插入,3、全写入)

//先找到偏移位
[fileHandle seekToFileOffset:3];

//写入转码后的数据
[fileHandle writeData:newData3];

1-6)、关闭操作

[fileHandle closeFile];

 

2、读取

2-1)、设置为读取模式

fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];

2-2)、读取数据

//读取所有data
NSData *readData = [fileHandle readDataToEndOfFile];

//转成字符串
NSString *readString = [[NSString alloc]initWithData:readData encoding:NSUTF8StringEncoding];

2-3)、再次读取数据

//设置为读取模式,否则有问题
fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];

2-4)、读取前几个数据

//读取
readData = [fileHandle readDataOfLength:10];

//转成字符串
readString = [[NSString alloc]initWithData:readData encoding:NSUTF8StringEncoding];

2-5)、关闭操作

[fileHandle closeFile];

 

==================== NSCache ====================

1、属性

// 自定义名字,以做区分
name;
// 最多存放 数据大小 eg.10*1000(好像在哪看到,苹果的GB、MB、KB 是1000 ,不是1024,不一定正确)
totalCostLimit;
// 最多存放 个数 eg.5
countLimit;
// 移除 废弃内容 的对象
evictsObjectsWithDiscardedContent;

2、方法

// 按 key 取对象
- (nullable ObjectType)objectForKey:(KeyType)key;
// 按 key 设置新的对象
- (void)setObject:(ObjectType)obj forKey:(KeyType)key; 
// 按 key 设置新的对象	cost:指定花费内存大小?
- (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)g;
// 按 key 移除对象
- (void)removeObjectForKey:(KeyType)key;
// 移除所有对象
- (void)removeAllObjects;

3、代理

//  代理
delegate;
// 签代理,可选项
// 对象将要移除,可根据需要保存在手机上。
- (void)cache:(NSCache *)cache willEvictObject:(id)obj;

 

 

附录:

 

==================== 沙盒文件夹、文件大小 ====================

1、单个文件大小

- (unsigned long long)fileSizeAtPath:(NSString*)filePath
{
    unsigned long long fileSize = 0;
    
    NSFileManager *manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:filePath]){
        fileSize = [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
    }
    return fileSize;
}

2、整个文件夹下的大小,以M为单位

- (float)folderSizeAtPath:(NSString*)folderPath
{
    NSFileManager *manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:folderPath] == NO) {
        return 0;
    }
    
    NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];
    NSString *fileName;
    unsigned long long folderSize = 0;
    while ((fileName = [childFilesEnumerator nextObject]) != nil){
        NSString *fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
        folderSize += [self fileSizeAtPath:fileAbsolutePath];
    }
    return folderSize/(1000.0*1000.0);
}

3、判断是M还是G,并以字符显示

- (NSString*)getCachesString
{
    CGFloat size = [self folderSizeAtPath:[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) firstObject]];
    
    if (size >= 1000.0 ){       // 大于1G
        return [NSString stringWithFormat:@"%.1fG",size/1000.0];
    }else{                                  // 最小以M为单位
        return [NSString stringWithFormat:@"%.1fM",size];
    }
}

 

==================== 清除沙盒 Library / Cache 下所有数据 ====================

1、清除文件夹

- (void)clearFileAtPath:(NSString*)filePath{
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSArray *filePathsArray = [fileManager contentsOfDirectoryAtPath:filePath error:nil];
    
    for (NSString *fileName in filePathsArray) {
        [fileManager removeItemAtPath:[filePath stringByAppendingPathComponent:fileName]
                                error:nil];
    }
}

2、清除沙盒 Library / Cache

- (void)clearLibCashesAllFile{
    NSString *cachesFilePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) firstObject];
    [self clearFileAtPath:cachesFilePath];
}

 

==================== 测试plist ====================

1、获取应用名称

// 获取应用名称
- (NSString*)getAppName
{
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    NSString *appName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
    if (!appName) {
        appName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];
    }
    return appName;
}

2、获取版本号

// 版本号
- (NSString*)getVersion
{
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    NSString *version = [bundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
    return version;
}

3、指向桌面测试plist文件的路径,没有的话再创建

- (NSString*)testPlistName:(NSString*)plistName
{
    NSString *bundle =  [[NSBundle mainBundle] resourcePath];
    NSString *bundle_desktop = [[bundle substringToIndex:[bundle rangeOfString:@"Library"].location] stringByAppendingFormat:@"Desktop"];
    NSString *bundle_desktop_appName = [bundle_desktop stringByAppendingPathComponent:[self getAppName]];
    NSString *bundle_desktop_appName_version = [bundle_desktop_appName stringByAppendingPathComponent:[NSString stringWithFormat:@"version %@",[self getVersion]]];
    
    NSString *plistPath = [NSString stringWithFormat:@"%@.plist",plistName];
    NSString *location = [bundle_desktop_appName_version stringByAppendingPathComponent:plistPath];
    
    NSError *error;
    if ([[NSFileManager defaultManager] fileExistsAtPath:bundle_desktop_appName] == NO) {
        [[NSFileManager defaultManager] createDirectoryAtPath:bundle_desktop_appName withIntermediateDirectories:YES attributes:nil error:&error];
    }
    
    if ([[NSFileManager defaultManager] fileExistsAtPath:bundle_desktop_appName_version] == NO) {
        [[NSFileManager defaultManager] createDirectoryAtPath:bundle_desktop_appName_version withIntermediateDirectories:YES attributes:nil error:&error];
    }
    return location;
}

  

 

posted on 2017-08-14 16:28  leonlincq  阅读(599)  评论(0编辑  收藏  举报