数据持久化存储的方法:
iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么.
documents,Library ,tmp app。
(NSHomeDirectory()),路径是一串数字和字母是一个app的内容
手动保存的文件在documents文件里
1、Documents目录:您应该将所有的应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。
3、Library目录:这个目录下有两个子目录:Caches和 Preferences
Preferences 目录:包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.
Caches 目录:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。
4、tmp目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。
2、AppName.app目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。
获取这些目录路径的方法:Domain领域 Mask面具,掩护,掩饰
1,获取家目录路径的函数:
NSString *homeDir = NSHomeDirectory();
2,获取Documents目录路径的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *docDir = [paths objectAtIndex:0];
3,获取Caches目录路径的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES);
NSString *cachesDir = [paths objectAtIndex:0];
4,获取tmp目录路径的方法:
NSString *tmpDir = NSTemporaryDirectory();
5,获取应用程序程序包中资源文件路径的方法:
例如获取程序包中一个图片资源(apple.png)路径的方法:
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@”apple” ofType:@”png”];
UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];
代码中的mainBundle类方法用于返回一个代表应用程序包的对象。
一,简单介绍一下常用的plist文件。
全名是:Property List,属性列表文件,它是一种用来存储串行化后的对象的文件。属性列表文件的扩展名为.plist ,因此通常被称为 plist文件。文件是xml格式的。
Plist文件通常用于储存用户设置,也可以用于存储捆绑的信息
二,先说文件保存到的几个位置:
1,工程自身里(**.app 右键显示包内容,plist文件就在这里)
2,工程沙盒里(保存到user Document下,不过不需要读写文件,用系统的 NSUserDefaults 可以快速保存添加读取删除基本数据类型,类似于Android里的Sharedpreferences )
3,Plist文件里面只能存储数组字典(NSArray,NSDictionary,NSNumber,NSString)等基本数据类型
[objc] view plain copy
- //读取xcode自动生成的plist文件, Info plist(注意大小写)
- NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
- NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
- NSLog(@"%@", data);
- //读取手动添加的plist文件
- NSString * selfPlistPath = [[NSBundle mainBundle] pathForResource:@"self" ofType:@"plist"];
- NSLog(@"selfPlistPath = %@", selfPlistPath);
- if([[NSFileManager defaultManager] fileExistsAtPath:selfPlistPath])
- {
- NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];
- NSLog(@"Data = %@", data);//直接打印数据。
- }
- //设置xcode自动生成的plist文件属性值,没有的数据就新建,已有的数据就修改
- [data setObject:@"逗比1" forKey:@"name"];
- [data setObject:@"dbdbdb" forKey:@"password"];
- //写入文件
- [data writeToFile:plistPath atomically:YES];
2.NSUserDefault 存储在Preferences文件夹里面
#pragma mark 1.NSUserDeaults ( Bool Double NSInteger float 对象要归档成NSData类型 [NSKeyedArchiver archivedDataWithRootObject:obj] )
//4.NSUserDeaults
//获取NSUserDeaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
/*
//存储BOOL值
[defaults setBool:<#(BOOL)#> forKey:(NSString *)]
//存储Double值
[defaults setDouble:<#(double)#> forKey:<#(NSString *)#>]
存储NSInteger值
[defaults setInteger:(NSInteger) forKey:(NSString *)]
存储float值
[defaults setFloat:<#(float)#> forKey:(NSString *)]
//存对象:NSString、NSArray、NSDictionary、NSNumber、NSData
[defaults setObject:<#(id)#> forKey:<#(NSString *)#>]
[defaults setValue:<#(id)#> forKey:<#(NSString *)#>]
[defaults setURL:<#(NSURL *)#> forKey:<#(NSString *)#>]
//用NSUserDeaults存储文字
[defaults setObject:textField.text forKey:@"text"];
//同步数据
[defaults synchronize];
//读取NSUserDefaults的值
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
UILabel *label = (id)[self.view viewWithTag:10];
label.text = [defaults objectForKey:@"text"];
注意:如果要存储自己定义的继承于NSObject的对象,先归档成NSData通过setObject:去存储
//存自定义的对象的时候
@interface TestObj : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSInteger age;
@end
@implementation TestObj
//反归档
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
//用key去解码
_name = [aDecoder decodeObjectForKey:@"name"];
_age = [aDecoder decodeIntegerForKey:@"age"];
}
returnself;
}
//归档时会调用这个方法
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInteger:_age forKey:@"age"];
}
@end
TestObj *obj = [[TestObj alloc]init];
obj.name = textField.text;
obj.age = 25;
//要存存一个自定义的类的对象到NSUserDefaults里,需要归档成NSData类型,再存进去 (如果是自定义的对象必须遵循coding协议并且实现方法)
//归档
NSData *objData = [NSKeyedArchiver archivedDataWithRootObject:obj];
[defaults setObject:objData forKey:@"obj"];
//取出自定义的对象的Data
NSData *objData = [defaults objectForKey:@"obj"];
//取出来之后反归档
TestObj *obj = [NSKeyedUnarchiver unarchiveObjectWithData:objData];
NSLog(@"name:%@,age:%ld",obj.name,obj.age);
3.归档和反归档 (对象存进沙盒)
NSCoding可以存储任意对象到沙盒中,只要遵守他的Coding协议即可
归档分为三种情况
1.一个对象归档到一个文件中
2.多个对象归档到一个文件中
3.自定义类型的对象归档
一、使用archiveRootObject进行归档,unarchiveObjectWithFile进行解档
使用NSKeyedArichiver进行归档、NSKeyedUnarchiver进行接档,这种方式会在写入、读出数据之前对数据进行序列化、反序列化操作。
归档:
NSString *homeDictionary = NSHomeDirectory();//获取根目录
NSString *homePath = [homeDictionary stringByAppendingPathComponent:@"atany.archiver"];//添加储存的文件名
BOOL flag = [NSKeyedArchiver archiveRootObject:@”归档” toFile:homePath];//归档一个字符串
这种方式可以对字符串、数字等进行归档,当然也可以对NSArray与NSDictionary进行归档。返回值Flag标志着是否归档成功,YES为成功,NO为失败。
解档:
[NSKeyedUnarchiver unarchiveObjectWithFile:homePath]
使用NSKeyedUnarchiver进行接档(反序列化)。
这种归档的方式存在一个缺点:只能把一个对象归档进一个文件中,那么怎么对多个对象进行归档呢?
二,使用NSKeyedArchiver和NSKeyedUnarchiver对非自定义对象进行归档
//-----归档 用到NSMutableData
NSArray *array = [NSArray arrayWithObjects:@"zhangsan",@"lisi",nilnil];
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
//编码
[archiver encodeObject:array forKey:@"array"];
[archiver encodeInt:100 forKey:@"scope"];
[archiver encodeObject:@"jack" forKey:@"name"];
//完成编码,将上面的归档数据填充到data中,再将data写入
[archiver finishEncoding];
NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.src"];
//将Data writetofile
BOOL success = [data writeToFile:filePath atomically:YES];
if(success){
NSLog(@"归档成功");
}
//-----解档 用到NSMutableData
NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.src"];
//读取归档数据
//从路径中initWithContentsOfFile出来data
NSMutableData *data = [[NSMutableData alloc] initWithContentsOfFile:filePath];
//创建解归档对象,对data中的数据进行解归档
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
//解档
NSArray *array = [unarchiver decodeObjectForKey:@"array"];
NSLog(@"%@",array);
int value = [unarchiver decodeObjectForKey:@"scope"];
NSLog(@"%d",value);
[unarchiver finishDecoding];
三,自定义对象归档到一个文件中(【注】:要将一个自定义的类进行归档,那么类里面的每个属性都必须是可以被归档的,如果是不能归档的类型,我们可以把他转化为NSValue进行归档,然后在读出来的时候在转化为相应的类。
)
// 自定义对象并且是单个对象归档,当然也可以使用二中的方法不过就是有点麻烦了
#define HWAccountPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.archive"]
HWAccount *account = [HWAccount accountWithDict:responseObject];
//是自定义的对象必须遵循coding协议并且实现方法)
[NSKeyedArchiver archiveRootObject:account toFile:path];
// 解档数据
HWAccount *account = [NSKeyedUnarchiver unarchiveObjectWithFile:HWAccountPath];
//归档解档
/**
* 当一个对象要归档进沙盒中时,就会调用这个方法
* 目的:在这个方法中说明这个对象的哪些属性要存进沙盒
*/
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.access_token forKey:@"access_token"];
[encoder encodeObject:self.expires_in forKey:@"expires_in"];
[encoder encodeObject:self.uid forKey:@"uid"];
}
/**
* 当从沙盒中解档一个对象时(从沙盒中加载一个对象时),就会调用这个方法
* 目的:在这个方法中说明沙盒中的属性该怎么解析(需要取出哪些属性)
*/
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
self.access_token = [decoder decodeObjectForKey:@"access_token"];
self.expires_in = [decoder decodeObjectForKey:@"expires_in"];
self.uid = [decoder decodeObjectForKey:@"uid"];
}
returnself;
}
四.NSFileManager的使用
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * path = @"/Users/aplle/Desktop/test.txt";
NSError * error;
NSDictionary * dic = [fileManager attributesOfItemAtPath:path error:&error];
NSLog(@"dic %@",dic);
if (error == nil)
{
NSDate * date = [dic objectForKey:NSFileCreationDate];
NSString * size = [dic objectForKey:NSFileSize];
NSLog(@" date = %@, size = %@",date,size);
}
//1 创建目录
//withIntermediateDirectories YES 逐级创建文件夹,NO表示只能够创建一级目录
BOOL isCreateSuccess = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
//2 移动目录移动就是剪切操作
/*
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * path = @"/Users/aplle/Desktop/myfolder";
NSString * pathTo = @"/Users/aplle/Desktop/newmyfolder";
NSError * error ;
BOOL isMoveSuccess = [fileManager moveItemAtPath:path toPath:pathTo error:&error];
//3.删除目录
/*
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * path = @"/Users/aplle/Desktop/newmyfolder";
NSError * error;
BOOL isRemoveSuccess = [fileManager removeItemAtPath:path error:&error];
//4.拷贝文件目录到一个地方
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * path = @"/Users/aplle/Desktop/myfolder";
NSString * pathTo = @"/Users/aplle/Desktop/newmyfolder";
NSError * error;
BOOL isCopySuccess = [fileManager copyItemAtPath:path toPath:pathTo error:&error];
//1.获得文件,写文件,读文件
//mp3.mp4 rmvb mkv pdf doc txt
/*
NSString * path = @"/Users/aplle/Desktop/屏幕快照 .png";
NSData * data = [NSData dataWithContentsOfFile:path];
BOOL isCreateSuccess = [fileManager createFileAtPath:pathTo contents:data attributes:nil];
//写文件
BOOL res=[content writeToFile:testPath atomically:YESencoding:NSUTF8StringEncoding error:nil];
if (res) {
NSLog(@"文件写入成功");
}else
NSLog(@"文件写入失败");
//读文件
// NSData *data = [NSData dataWithContentsOfFile:testPath];
// NSLog(@"文件读取成功: %@",//将NSData转化成NSString
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
NSString *content=[NSString stringWithContentsOfFile:testPath encoding:NSUTF8StringEncoding error:nil];
NSLog(@"文件读取成功: %@",content);
//注意区分这三个方法的区别前两个是类方法,最后一个是data的init方法
stringWithContentsOfFile dataWithContentsOfFile initWithContentsOfFile
}
/*
//2.移动文件相当于剪切操作
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * path = @"/Users/aplle/Desktop/屏幕快照 .png";
NSString * pathTo = @"/Users/aplle/Desktop/newmyfolder/屏幕屏幕.png";
NSError * error;
BOOL ismoveSuccess = [fileManager moveItemAtPath:path toPath:pathTo error:&error];
//3.删除文件
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * path = @"/Users/aplle/Desktop/屏幕快照副本.png";
NSError * error;
BOOL isremove = [fileManager removeItemAtPath:path error:&error];
//获得路径下的内容,只能获取当前路径下的目录
NSArray * array=[fm contentsOfDirectoryAtPath:path error:nil];
//能够逐级的获得所有子集的目录
NSArray * array = [fileManager subpathsOfDirectoryAtPath:path error:&error];
//路径拼接的方法,自动添加 /
NSString * subPath=[path stringByAppendingPathComponent:name];
BOOL isDirectory;
//检查指定的路径是否存在,同时它是文件还是文件夹
BOOL isExists=[fm fileExistsAtPath:subPath isDirectory:&isDirectory];//directory目录
//检查指定的路径是否存在
if ([fm fileExistsAtPath:@"/Users/leisure/Desktop/1512/day9"]) {
-(void)moveFileWithGCD
{
//1.拿到文件路径
NSString *from = @"/Users/xiaomage/Desktop/from";
//2.获得目标文件路径
NSString *to = @"/Users/xiaomage/Desktop/to";
//3.得到目录下面的所有文件
NSArray *subPaths = [[NSFileManager defaultManager] subpathsAtPath:from];
NSLog(@"%@",subPaths);
//4.遍历所有文件,然后执行剪切操作
NSInteger count = subPaths.count;
dispatch_apply(count, dispatch_get_global_queue(0, 0), ^(size_t i) {
//4.1 拼接文件的全路径
// NSString *fullPath = [from stringByAppendingString:subPaths[i]];
// 在拼接的时候会自动添加/ 上面那个不添加/
NSString *fullPath = [from stringByAppendingPathComponent:subPaths[i]];
NSString *toFullPath = [to stringByAppendingPathComponent:subPaths[i]];
NSLog(@"%@",fullPath);
//4.2 执行剪切操作
/*
第一个参数:要剪切的文件在哪里
第二个参数:文件应该被存到哪个位置
*/
[[NSFileManager defaultManager]moveItemAtPath:fullPath toPath:toFullPath error:nil];
NSLog(@"%@---%@--%@",fullPath,toFullPath,[NSThread currentThread]);
});
}
//音频文件,文本文件,视频文件就必须使用NSData数据类,如果是字符串就可以直接写
/*
NSString * str = @"www.itcast.cn";
NSError * error;
[str writeToFile:@"/Users/aplle/Desktop/text.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error];
*/
/*
NSString * path = @"/Users/aplle/Desktop/text.txt";
//把目标文件加载到内存中.
//NSData 是不可变长度的Data类型,只能够通过一次加载完成所有的数据
NSData * data = [NSData dataWithContentsOfFile:path];
NSLog(@"data length %ld",data.length);
NSString * pathTo = @"/Users/aplle/Desktop/nextext.txt";
//把加载到内存中的文件,写入到指定的位置
BOOL isWriteSuccess = [data writeToFile:pathTo atomically:YES];
//当需要把多个NSData数据拼接成一个数据存储的时候,就要想到使用NSMutableData这个类型
NSString * str1 = @"好好学习";
NSString * str2 = @"天天向上";
NSString * str3 = @"今天休息";
NSMutableData * muData = [[NSMutableData alloc] init];
NSData * d1 = [str1 dataUsingEncoding:NSUTF8StringEncoding];
NSData * d2 = [str2 dataUsingEncoding:NSUTF8StringEncoding];
NSData * d3 = [str3 dataUsingEncoding:NSUTF8StringEncoding];
//appendData 能够把nsdata对象加入到 muData对象中
[muData appendData:d1];
[muData appendData:d2];
[muData appendData:d3];
NSString * path =@"/Users/aplle/Desktop/传智播客校训.txt";
//NSMutableData是继承至NSData的所以可以调用writeToFile把数据写入到一个指定的目录下
BOOL iswriteSucess = [muData writeToFile:path atomically:YES];
Plist文件NSUserDefault以及NSCoding都不能存储大数据,因为上面三种方法存储的时候都会把新的数据覆盖旧的数据,每次存储还要重新读取数据
#import "DataBaseManager.h"
#import "NewsModel.h"
#define NEWS_TABLE @"newsTable" //新闻数据表
// 打印数据库相关错误信息
#define DATABASE_ERROR NSLog(@"%@", _dataBase.lastErrorMessage);
// 面试题结合宏定义 一般会出现 优先级的问题
// 2 + 3 * 5
@interface DataBaseManager ()
{
// 线程锁 目的:为了避免同一时间,对某条数据进行多次修改
NSLock * _lock;
}
@end
@implementation DataBaseManager
+(DataBaseManager *)sharedDataBaseManager
{
static DataBaseManager * manager =nil;
@synchronized(self) {
if(manager ==nil){
manager = [[DataBaseManager alloc] init];
}
}
return manager;
}
-(instancetype)init
{
if(self = [super init]){
// 获取沙盒目录
NSLog(@"%@", NSHomeDirectory());
// Documents 由用户自己生成的文件,2当手机和电脑链接,通过iTunes可以看到此目录内容
// Library 从网络上下载的内容,要缓存到此目录下,
// tmp 临时目录,变动较大,不建议放在此目录
_lock = [[NSLock alloc] init];
// 由上得到db文件路径 后缀名为.db或者.sqlite
NSString * dbPath = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:@"richy.db"];
NSLog(@"path = %@", dbPath);
// 2. [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/richy.db"]
// 3. NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
// 路径是数据库db文件的路径
// 内部处理:如果该路径下db文件存在,不会重新创建。反之不存在才会创建
_dataBase = [[FMDatabase alloc] initWithPath:dbPath];
}
returnself;
}
-(void)createNewsTable
{
if([_dataBase open]){
// 如果数据库打开,进行后续的操作
// 创建表 sql语句
// 二进制数据类型 blob
NSString * sql = [NSString stringWithFormat:@"create table if not exists %@ (myId varchar(10) primary key, title text, comment_count varchar(32), source text, icon text, shortDesc text)", NEWS_TABLE];
BOOL isSuccess = [_dataBase executeUpdate:sql];
if(!isSuccess){
DATABASE_ERROR
}
}
}
// 增加
-(void)insertNewsModel:(NewsModel *)model
{
// 上锁
[_lock lock];
if([_dataBase open]){
// 通过?占位符
// 数据类型
// age 不能直接传23 需要转成对象类型 NSNumber
// 如果有空数据 应该传NULL
NSString * sql = [NSString stringWithFormat:@"insert into %@ (myId, title, icon, shortDesc) values(?, ?, ?, ?)", NEWS_TABLE];
BOOL isInsert = [_dataBase executeUpdate:sql, model.myId, model.title, model.icon, model.shortDesc];
if(!isInsert){
DATABASE_ERROR
}
// 关闭数据库 为避免数据库闲置,减少占用
[_dataBase close];
}
// 解锁,允许其他人能够进行此操作
[_lock unlock];
}
// 删除
-(void)deleteNewsModel:(NewsModel *)model
{
[_lock lock];
if([_dataBase open]){
NSString * sql = [NSString stringWithFormat:@"delete from %@ where myId = ?", NEWS_TABLE];
BOOL isDelete = [_dataBase executeUpdate:sql, model.myId];
if(!isDelete){
DATABASE_ERROR
}
// 关闭数据库 为避免数据库闲置,减少占用
[_dataBase close];
}
[_lock unlock];
}
// 查看数据
-(NSArray *)findAllNewsList
{
// 临时存储所有数据模型
NSMutableArray * dataSource = [[NSMutableArray alloc] init];
if([_dataBase open]){
NSString * sql = [NSString stringWithFormat:@"select * from %@", NEWS_TABLE];
// 注意方法⚠️:executeQuery 最终得到查询的结果
FMResultSet * result = [_dataBase executeQuery:sql];
while ([result next]) {
NewsModel * model = [[NewsModel alloc] init];
// 得到name字段 所对应的值
model.myId = [result stringForColumn:@"myId"];
model.title = [result stringForColumn:@"title"];
model.comment_count = [result stringForColumn:@"comment_count"];
model.source = [result stringForColumn:@"source"];
model.icon = [result stringForColumn:@"icon"];
model.shortDesc = [result stringForColumn:@"shortDesc"];
[dataSource addObject:model];
}
// 关闭数据库 为避免数据库闲置,减少占用
[_dataBase close];
}
return dataSource;
}
-(BOOL)isExistNewsModel:(NewsModel *)model
{
if([_dataBase open]){
NSString * sql = [NSString stringWithFormat:@"select * from %@ where myId = %@", NEWS_TABLE, model.myId];
// 注意方法⚠️:executeQuery 最终得到查询的结果
FMResultSet * result = [_dataBase executeQuery:sql];
while ([result next]) {
// 证明数据库中有这个数据
returnYES;
}
// 关闭数据库 为避免数据库闲置,减少占用
[_dataBase close];
}
returnNO;
}
@end
//写文件,获取文件属性
/*
NSString * str = @"www.itcast.cn";
NSError * error;
BOOL isWriteSuccess = [str writeToFile:@"/Users/aplle/Desktop/test.txt" atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (isWriteSuccess)
{
NSLog(@"创建成功");
}
else
{
NSLog(@"error %@",error);
}
*/
//1.获取文件管理器
NSFileManager * fileManager = [NSFileManager defaultManager];
NSString * path = @"/Users/aplle/Desktop/test.txt";
NSError * error;
NSDictionary * dic = [fileManager attributesOfItemAtPath:path error:&error];
NSLog(@"dic %@",dic);
if (error == nil)
{
NSDate * date = [dic objectForKey:NSFileCreationDate];
NSString * size = [dic objectForKey:NSFileSize];
NSLog(@" date = %@, size = %@",date,size);
}
}
return 0;
}