最近再完善自己的下载器,JKDownloader,我的原则就是只存下载文件缓存,不存任何数据到文件和或者数据库或者userdefault等等区域。
那问题就来了,当app重新打开如何知道文件的下载进度呢?
存在文件名中?或者存在文件内部?
结果最好的方案那就是需要把自定义的一些数据(文件总大小啦,文件下载百分比等等啦)写入到文件的扩展属性中了。
两种不同的方式来实现:
通过NSFileManager一个特殊的AttributeName
- (BOOL)setExtendedAttribute:(NSString*)attribute forKey:(NSString*)key withPath:(NSString*)path{
NSData *data = [NSPropertyListSerialization dataWithPropertyList:attribute format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil];
NSError *error;
BOOL sucess = [[NSFileManager defaultManager] setAttributes:@{@"NSFileExtendedAttributes":@{key:data}}
ofItemAtPath:path error:&error];
return sucess;
}
- (id)getExtendedAttributeForKey:(NSString*)key withPath:(NSString*)path{
NSError *error;
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error];
if (!attributes) {
return nil;
}
NSDictionary *extendedAttributes = [attributes objectForKey:@"NSFileExtendedAttributes"];
if (!extendedAttributes) {
return nil;
}
NSData *data = [extendedAttributes objectForKey:key];
id plist = [NSPropertyListSerialization propertyListWithData:data options:0 format:NSPropertyListImmutable error:nil];
return [plist description];
}
通过sys/xattr.h的函数实现
#include <sys/xattr.h>
//为文件增加一个扩展属性
- (BOOL)extended1WithPath:(NSString *)path key:(NSString *)key value:(NSData *)value
{
ssize_t writelen = setxattr([path fileSystemRepresentation],
[key UTF8String],
[value bytes],
[value length],
0,
0);
return writelen==0?YES:NO;
}
//读取文件扩展属性
- (NSData *)extended1WithPath:(NSString *)path key:(NSString *)key
{
ssize_t readlen = 1024;
do {
char buffer[readlen];
bzero(buffer, sizeof(buffer));
size_t leng = sizeof(buffer);
readlen = getxattr([path fileSystemRepresentation],
[key UTF8String],
buffer,
leng,
0,
0);
if (readlen < 0){
return nil;
}
else if (readlen > sizeof(buffer)) {
continue;
}else{
NSData *result = [NSData dataWithBytes:buffer length:readlen];
return result;
}
} while (YES);
return nil;
}
NSFileExtendedAttributes字典对应的是一个NSData,NSData需要用NSPropertyListSerialization解析。
以下是文件所有的属性。
//通过NSFileManager获取文件的属性 NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:NULL]; NSLog(@"%@",attributes);
Printing description of attributes:
{
NSFileCreationDate = "2017-09-07 05:56:38 +0000";
NSFileExtendedAttributes = {
JKDownloaderExpectedFileSize = <62706c69 73743030 58343730 31343130 37080000 00000000 01010000 00000000 00010000 00000000 00000000 00000000 0011>;
};
NSFileExtensionHidden = 0;
NSFileGroupOwnerAccountID = 20;
NSFileGroupOwnerAccountName = staff;
NSFileModificationDate = "2017-09-07 06:26:32 +0000";
NSFileOwnerAccountID = 501;
NSFilePosixPermissions = 420;
NSFileReferenceCount = 1;
NSFileSize = 12432269;
NSFileSystemFileNumber = 70334415;
NSFileSystemNumber = 16777217;
NSFileType = NSFileTypeRegular;
}
是不是很酷?
Done!
转载请注明:天狐博客 » iOS/Mac开发之为文件增加自定义的扩展属性(NSFileExtendedAttributes)