最近遇到一个需求,因为之前项目数据库设计的不合理,把数据库位置位置放在了Documents文件下,现在有个需要使用文件共享的功能,将Documents文件夹暴露给用户,让他们能够将下载的小说或者音乐直接拷走,但是因为我们的数据库也在Documents文件下,用户随便就能考走数据库文件,这肯定是不合理的,╮(╯﹏╰)╭,于是,我们只能对这个功能进行修改了。然后我们就想了2个方案,一个是移动数据库的位置,一个是隐藏数据库,然后上网查了下,感觉隐藏数据库会简单很多,只需将文件名前面加个.就能将文件隐藏,于是,我们便决定使用隐藏数据库这个方案。
在隐藏数据库之前,我们必须对之前版本进行兼容,于是,我们便打算先走一个判断是之前文件是否存在然后再进行改名或者创建文件的办法:
#define DataBaseName_1 @"DataBase_1.db"
#define DataBaseName_2 @".DataBase_2.db"
//获取之前文件夹的位置
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSString *dataBasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:DataBaseName_1]];
//隐藏文件夹,只需在文件名字前加个.就可以将文件隐藏
NSString *dataBasePath2 = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:DataBaseName_2]];
BOOL hasFile2 = [filemanager fileExistsAtPath:dataBasePath2];
更改文件名字用到rename (const char *__old, const char *__new)这个C语言函数,顾名思义,第一个参数传的老文件名字,第二个传入要改的名字,返回0是修改文件名成功,返回-1则失败。
之后想想可能会出现的3种情况,用户第一次使用APP,无DataBase1和DataBase2;第二种情况,老用户升级,有DataBase1无DataBase2;已经升级完成的用户,有DataBase2无DataBase1(DataBase1为之前的文件,DataBase2为隐藏文件)
//使用NSFileManager判断是否存在这个文件
NSFileManager *filemanager = [NSFileManager defaultManager];
BOOL hasFile = [filemanager fileExistsAtPath:dataBasePath];
//无DataBase1
if(NO == hasFile){
if(NO == hasFile2){
//新用户,无DataBase1和DataBase2,直接创建隐藏数据库文件,然后打开数据库
}else{
//已经升级完成的用户,直接打开数据库2即可
}
}else{
//有DataBase1无DataBase2,需要更新,更新文件名字,只需要一行很简单的代码即可
const char *dbpath = [dataBasePath UTF8String];
const char *dbpath2 = [dataBasePath2 UTF8String];
if (rename(dbpath, dbpath2) != 0) {
NSLog(@"Unable to Change DatabaseName");
return;
}
//已经完成改名,之后直接打开数据库2即可
}