Quantcast
Channel: 天狐博客
Viewing all articles
Browse latest Browse all 115

iOS/Mac开发之为文件增加自定义的扩展属性(NSFileExtendedAttributes)

$
0
0

最近再完善自己的下载器,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)


Viewing all articles
Browse latest Browse all 115

Trending Articles