//
|
// FCFileManager.m
|
//
|
// Created by Fabio Caccamo on 28/01/14.
|
// Copyright (c) 2014 Fabio Caccamo. All rights reserved.
|
//
|
|
#import "FCFileManager.h"
|
#import <sys/xattr.h>
|
|
@implementation FCFileManager
|
|
|
+(NSMutableArray *)absoluteDirectories
|
{
|
static NSMutableArray *directories = nil;
|
static dispatch_once_t token;
|
|
dispatch_once(&token, ^{
|
|
directories = [NSMutableArray arrayWithObjects:
|
[self pathForApplicationSupportDirectory],
|
[self pathForCachesDirectory],
|
[self pathForDocumentsDirectory],
|
[self pathForLibraryDirectory],
|
[self pathForMainBundleDirectory],
|
[self pathForTemporaryDirectory],
|
nil];
|
|
[directories sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
|
|
return (((NSString *)obj1).length > ((NSString *)obj2).length) ? 0 : 1;
|
|
}];
|
});
|
|
return directories;
|
}
|
|
|
+(NSString *)absoluteDirectoryForPath:(NSString *)path
|
{
|
[self assertPath:path];
|
|
if([path isEqualToString:@"/"])
|
{
|
return nil;
|
}
|
|
NSMutableArray *directories = [self absoluteDirectories];
|
|
for(NSString *directory in directories)
|
{
|
NSRange indexOfDirectoryInPath = [path rangeOfString:directory];
|
|
if(indexOfDirectoryInPath.location == 0)
|
{
|
return directory;
|
}
|
}
|
|
return nil;
|
}
|
|
|
+(NSString *)absolutePath:(NSString *)path
|
{
|
[self assertPath:path];
|
|
NSString *defaultDirectory = [self absoluteDirectoryForPath:path];
|
|
if(defaultDirectory != nil)
|
{
|
return path;
|
}
|
else {
|
return [self pathForDocumentsDirectoryWithPath:path];
|
}
|
}
|
|
|
+(void)assertPath:(NSString *)path
|
{
|
NSAssert(path != nil, @"Invalid path. Path cannot be nil.");
|
NSAssert(![path isEqualToString:@""], @"Invalid path. Path cannot be empty string.");
|
}
|
|
|
+(id)attributeOfItemAtPath:(NSString *)path forKey:(NSString *)key
|
{
|
return [[self attributesOfItemAtPath:path] objectForKey:key];
|
}
|
|
|
+(id)attributeOfItemAtPath:(NSString *)path forKey:(NSString *)key error:(NSError **)error
|
{
|
return [[self attributesOfItemAtPath:path error:error] objectForKey:key];
|
}
|
|
|
+(NSDictionary *)attributesOfItemAtPath:(NSString *)path
|
{
|
return [self attributesOfItemAtPath:path error:nil];
|
}
|
|
|
+(NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
return [[NSFileManager defaultManager] attributesOfItemAtPath:[self absolutePath:path] error:error];
|
}
|
|
|
+(BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath
|
{
|
return [self copyItemAtPath:path toPath:toPath overwrite:NO error:nil];
|
}
|
|
|
+(BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath error:(NSError **)error
|
{
|
return [self copyItemAtPath:path toPath:toPath overwrite:NO error:error];
|
}
|
|
|
+(BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite
|
{
|
return [self copyItemAtPath:path toPath:toPath overwrite:overwrite error:nil];
|
}
|
|
|
+(BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite error:(NSError **)error
|
{
|
if(![self existsItemAtPath:toPath] || (overwrite && [self removeItemAtPath:toPath error:error] && [self isNotError:error]))
|
{
|
if([self createDirectoriesForFileAtPath:toPath error:error])
|
{
|
BOOL copied = [[NSFileManager defaultManager] copyItemAtPath:[self absolutePath:path] toPath:[self absolutePath:toPath] error:error];
|
|
return (copied && [self isNotError:error]);
|
}
|
else {
|
return NO;
|
}
|
}
|
else {
|
return NO;
|
}
|
}
|
|
|
+(BOOL)createDirectoriesForFileAtPath:(NSString *)path
|
{
|
return [self createDirectoriesForFileAtPath:path error:nil];
|
}
|
|
|
+(BOOL)createDirectoriesForFileAtPath:(NSString *)path error:(NSError **)error
|
{
|
NSString *pathLastChar = [path substringFromIndex:(path.length - 1)];
|
|
if([pathLastChar isEqualToString:@"/"])
|
{
|
[NSException raise:@"Invalid path" format:@"file path can't have a trailing '/'."];
|
|
return NO;
|
}
|
|
return [self createDirectoriesForPath:[[self absolutePath:path] stringByDeletingLastPathComponent] error:error];
|
}
|
|
|
+(BOOL)createDirectoriesForPath:(NSString *)path
|
{
|
return [self createDirectoriesForPath:path error:nil];
|
}
|
|
|
+(BOOL)createDirectoriesForPath:(NSString *)path error:(NSError **)error
|
{
|
return [[NSFileManager defaultManager] createDirectoryAtPath:[self absolutePath:path] withIntermediateDirectories:YES attributes:nil error:error];
|
}
|
|
|
+(BOOL)createFileAtPath:(NSString *)path
|
{
|
return [self createFileAtPath:path withContent:nil overwrite:NO error:nil];
|
}
|
|
|
+(BOOL)createFileAtPath:(NSString *)path error:(NSError **)error
|
{
|
return [self createFileAtPath:path withContent:nil overwrite:NO error:error];
|
}
|
|
|
+(BOOL)createFileAtPath:(NSString *)path overwrite:(BOOL)overwrite
|
{
|
return [self createFileAtPath:path withContent:nil overwrite:overwrite error:nil];
|
}
|
|
|
+(BOOL)createFileAtPath:(NSString *)path overwrite:(BOOL)overwrite error:(NSError **)error
|
{
|
return [self createFileAtPath:path withContent:nil overwrite:overwrite error:error];
|
}
|
|
|
+(BOOL)createFileAtPath:(NSString *)path withContent:(NSObject *)content
|
{
|
return [self createFileAtPath:path withContent:content overwrite:NO error:nil];
|
}
|
|
|
+(BOOL)createFileAtPath:(NSString *)path withContent:(NSObject *)content error:(NSError **)error
|
{
|
return [self createFileAtPath:path withContent:content overwrite:NO error:error];
|
}
|
|
|
+(BOOL)createFileAtPath:(NSString *)path withContent:(NSObject *)content overwrite:(BOOL)overwrite
|
{
|
return [self createFileAtPath:path withContent:content overwrite:overwrite error:nil];
|
}
|
|
|
+(BOOL)createFileAtPath:(NSString *)path withContent:(NSObject *)content overwrite:(BOOL)overwrite error:(NSError **)error
|
{
|
if(![self existsItemAtPath:path] || (overwrite && [self removeItemAtPath:path error:error] && [self isNotError:error]))
|
{
|
if([self createDirectoriesForFileAtPath:path error:error])
|
{
|
BOOL created = [[NSFileManager defaultManager] createFileAtPath:[self absolutePath:path] contents:nil attributes:nil];
|
|
if(content != nil)
|
{
|
[self writeFileAtPath:path content:content error:error];
|
}
|
|
return (created && [self isNotError:error]);
|
}
|
else {
|
return NO;
|
}
|
}
|
else {
|
return NO;
|
}
|
}
|
|
|
+(NSDate *)creationDateOfItemAtPath:(NSString *)path
|
{
|
return [self creationDateOfItemAtPath:path error:nil];
|
}
|
|
|
+(NSDate *)creationDateOfItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
return (NSDate *)[self attributeOfItemAtPath:path forKey:NSFileCreationDate error:error];
|
}
|
|
|
+(NSDate *)modificationDateOfItemAtPath:(NSString *)path
|
{
|
return [self modificationDateOfItemAtPath:path error:nil];
|
}
|
|
|
+(NSDate *)modificationDateOfItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
return (NSDate *)[self attributeOfItemAtPath:path forKey:NSFileModificationDate error:error];
|
}
|
|
|
+(BOOL)emptyCachesDirectory
|
{
|
return [self removeFilesInDirectoryAtPath:[self pathForCachesDirectory]];
|
}
|
|
|
+(BOOL)emptyTemporaryDirectory
|
{
|
return [self removeFilesInDirectoryAtPath:[self pathForTemporaryDirectory]];
|
}
|
|
|
+(BOOL)existsItemAtPath:(NSString *)path
|
{
|
return [[NSFileManager defaultManager] fileExistsAtPath:[self absolutePath:path]];
|
}
|
|
|
+(BOOL)isDirectoryItemAtPath:(NSString *)path
|
{
|
return [self isDirectoryItemAtPath:path error:nil];
|
}
|
|
|
+(BOOL)isDirectoryItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
return ([self attributeOfItemAtPath:path forKey:NSFileType error:error] == NSFileTypeDirectory);
|
}
|
|
|
+(BOOL)isEmptyItemAtPath:(NSString *)path
|
{
|
return [self isEmptyItemAtPath:path error:nil];
|
}
|
|
|
+(BOOL)isEmptyItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
return ([self isFileItemAtPath:path error:error] && ([[self sizeOfItemAtPath:path error:error] intValue] == 0)) || ([self isDirectoryItemAtPath:path error:error] && ([[self listItemsInDirectoryAtPath:path deep:NO] count] == 0));
|
}
|
|
|
+(BOOL)isFileItemAtPath:(NSString *)path
|
{
|
return [self isFileItemAtPath:path error:nil];
|
}
|
|
|
+(BOOL)isFileItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
return ([self attributeOfItemAtPath:path forKey:NSFileType error:error] == NSFileTypeRegular);
|
}
|
|
|
+(BOOL)isExecutableItemAtPath:(NSString *)path
|
{
|
return [[NSFileManager defaultManager] isExecutableFileAtPath:[self absolutePath:path]];
|
}
|
|
|
+(BOOL)isNotError:(NSError **)error
|
{
|
//the first check prevents EXC_BAD_ACCESS error in case methods are called passing nil to error argument
|
//the second check prevents that the methods returns always NO just because the error pointer exists (so the first condition returns YES)
|
return ((error == nil) || ((*error) == nil));
|
}
|
|
|
+(BOOL)isReadableItemAtPath:(NSString *)path
|
{
|
return [[NSFileManager defaultManager] isReadableFileAtPath:[self absolutePath:path]];
|
}
|
|
|
+(BOOL)isWritableItemAtPath:(NSString *)path
|
{
|
return [[NSFileManager defaultManager] isWritableFileAtPath:[self absolutePath:path]];
|
}
|
|
|
+(NSArray *)listDirectoriesInDirectoryAtPath:(NSString *)path
|
{
|
return [self listDirectoriesInDirectoryAtPath:path deep:NO];
|
}
|
|
|
+(NSArray *)listDirectoriesInDirectoryAtPath:(NSString *)path deep:(BOOL)deep
|
{
|
NSArray *subpaths = [self listItemsInDirectoryAtPath:path deep:deep];
|
|
return [subpaths filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
|
NSString *subpath = (NSString *)evaluatedObject;
|
|
return [self isDirectoryItemAtPath:subpath];
|
}]];
|
}
|
|
|
+(NSArray *)listFilesInDirectoryAtPath:(NSString *)path
|
{
|
return [self listFilesInDirectoryAtPath:path deep:NO];
|
}
|
|
|
+(NSArray *)listFilesInDirectoryAtPath:(NSString *)path deep:(BOOL)deep
|
{
|
NSArray *subpaths = [self listItemsInDirectoryAtPath:path deep:deep];
|
|
return [subpaths filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
|
NSString *subpath = (NSString *)evaluatedObject;
|
|
return [self isFileItemAtPath:subpath];
|
}]];
|
}
|
|
|
+(NSArray *)listFilesInDirectoryAtPath:(NSString *)path withExtension:(NSString *)extension
|
{
|
return [self listFilesInDirectoryAtPath:path withExtension:extension deep:NO];
|
}
|
|
|
+(NSArray *)listFilesInDirectoryAtPath:(NSString *)path withExtension:(NSString *)extension deep:(BOOL)deep
|
{
|
NSArray *subpaths = [self listFilesInDirectoryAtPath:path deep:deep];
|
|
return [subpaths filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
|
NSString *subpath = (NSString *)evaluatedObject;
|
NSString *subpathExtension = [[subpath pathExtension] lowercaseString];
|
NSString *filterExtension = [[extension lowercaseString] stringByReplacingOccurrencesOfString:@"." withString:@""];
|
|
return [subpathExtension isEqualToString:filterExtension];
|
}]];
|
}
|
|
|
+(NSArray *)listFilesInDirectoryAtPath:(NSString *)path withPrefix:(NSString *)prefix
|
{
|
return [self listFilesInDirectoryAtPath:path withPrefix:prefix deep:NO];
|
}
|
|
|
+(NSArray *)listFilesInDirectoryAtPath:(NSString *)path withPrefix:(NSString *)prefix deep:(BOOL)deep
|
{
|
NSArray *subpaths = [self listFilesInDirectoryAtPath:path deep:deep];
|
|
return [subpaths filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
|
NSString *subpath = (NSString *)evaluatedObject;
|
NSString *fileName = [subpath lastPathComponent];
|
|
return ([fileName hasPrefix:prefix] || [fileName isEqualToString:prefix]);
|
}]];
|
}
|
|
|
+(NSArray *)listFilesInDirectoryAtPath:(NSString *)path withSuffix:(NSString *)suffix
|
{
|
return [self listFilesInDirectoryAtPath:path withSuffix:suffix deep:NO];
|
}
|
|
|
+(NSArray *)listFilesInDirectoryAtPath:(NSString *)path withSuffix:(NSString *)suffix deep:(BOOL)deep
|
{
|
NSArray *subpaths = [self listFilesInDirectoryAtPath:path deep:deep];
|
|
return [subpaths filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
|
|
NSString *subpath = (NSString *)evaluatedObject;
|
NSString *subpathName = [subpath stringByDeletingPathExtension];
|
|
return ([subpath hasSuffix:suffix] || [subpath isEqualToString:suffix] || [subpathName hasSuffix:suffix] || [subpathName isEqualToString:suffix]);
|
}]];
|
}
|
|
|
+(NSArray *)listItemsInDirectoryAtPath:(NSString *)path deep:(BOOL)deep
|
{
|
NSString *absolutePath = [self absolutePath:path];
|
NSArray *relativeSubpaths = (deep ? [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:absolutePath error:nil] : [[NSFileManager defaultManager] contentsOfDirectoryAtPath:absolutePath error:nil]);
|
|
NSMutableArray *absoluteSubpaths = [[NSMutableArray alloc] init];
|
|
for(NSString *relativeSubpath in relativeSubpaths)
|
{
|
NSString *absoluteSubpath = [absolutePath stringByAppendingPathComponent:relativeSubpath];
|
[absoluteSubpaths addObject:absoluteSubpath];
|
}
|
|
return [NSArray arrayWithArray:absoluteSubpaths];
|
}
|
|
|
+(BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath
|
{
|
return [self moveItemAtPath:path toPath:toPath overwrite:NO error:nil];
|
}
|
|
|
+(BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath error:(NSError **)error
|
{
|
return [self moveItemAtPath:path toPath:toPath overwrite:NO error:error];
|
}
|
|
|
+(BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite
|
{
|
return [self moveItemAtPath:path toPath:toPath overwrite:overwrite error:nil];
|
}
|
|
|
+(BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite error:(NSError **)error
|
{
|
if(![self existsItemAtPath:toPath] || (overwrite && [self removeItemAtPath:toPath error:error] && [self isNotError:error]))
|
{
|
return ([self createDirectoriesForFileAtPath:toPath error:error] && [[NSFileManager defaultManager] moveItemAtPath:[self absolutePath:path] toPath:[self absolutePath:toPath] error:error]);
|
}
|
else {
|
return NO;
|
}
|
}
|
|
|
+(NSString *)pathForApplicationSupportDirectory
|
{
|
static NSString *path = nil;
|
static dispatch_once_t token;
|
|
dispatch_once(&token, ^{
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
|
path = [paths lastObject];
|
});
|
|
return path;
|
}
|
|
|
+(NSString *)pathForApplicationSupportDirectoryWithPath:(NSString *)path
|
{
|
return [[FCFileManager pathForApplicationSupportDirectory] stringByAppendingPathComponent:path];
|
}
|
|
|
+(NSString *)pathForCachesDirectory
|
{
|
static NSString *path = nil;
|
static dispatch_once_t token;
|
|
dispatch_once(&token, ^{
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
|
path = [paths lastObject];
|
});
|
|
return path;
|
}
|
|
|
+(NSString *)pathForCachesDirectoryWithPath:(NSString *)path
|
{
|
return [[FCFileManager pathForCachesDirectory] stringByAppendingPathComponent:path];
|
}
|
|
|
+(NSString *)pathForDocumentsDirectory
|
{
|
static NSString *path = nil;
|
static dispatch_once_t token;
|
|
dispatch_once(&token, ^{
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
|
path = [paths lastObject];
|
});
|
|
return path;
|
}
|
|
|
+(NSString *)pathForDocumentsDirectoryWithPath:(NSString *)path
|
{
|
return [[FCFileManager pathForDocumentsDirectory] stringByAppendingPathComponent:path];
|
}
|
|
|
+(NSString *)pathForLibraryDirectory
|
{
|
static NSString *path = nil;
|
static dispatch_once_t token;
|
|
dispatch_once(&token, ^{
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
|
|
path = [paths lastObject];
|
});
|
|
return path;
|
}
|
|
|
+(NSString *)pathForLibraryDirectoryWithPath:(NSString *)path
|
{
|
return [[FCFileManager pathForLibraryDirectory] stringByAppendingPathComponent:path];
|
}
|
|
|
+(NSString *)pathForMainBundleDirectory
|
{
|
return [NSBundle mainBundle].resourcePath;
|
}
|
|
|
+(NSString *)pathForMainBundleDirectoryWithPath:(NSString *)path
|
{
|
return [[FCFileManager pathForMainBundleDirectory] stringByAppendingPathComponent:path];
|
}
|
|
|
+(NSString *)pathForPlistNamed:(NSString *)name
|
{
|
NSString *nameExtension = [name pathExtension];
|
NSString *plistExtension = @"plist";
|
|
if([nameExtension isEqualToString:@""])
|
{
|
name = [name stringByAppendingPathExtension:plistExtension];
|
}
|
|
return [self pathForMainBundleDirectoryWithPath:name];
|
}
|
|
|
+(NSString *)pathForTemporaryDirectory
|
{
|
static NSString *path = nil;
|
static dispatch_once_t token;
|
|
dispatch_once(&token, ^{
|
|
path = NSTemporaryDirectory();
|
});
|
|
return path;
|
}
|
|
|
+(NSString *)pathForTemporaryDirectoryWithPath:(NSString *)path
|
{
|
return [[FCFileManager pathForTemporaryDirectory] stringByAppendingPathComponent:path];
|
}
|
|
|
+(NSString *)readFileAtPath:(NSString *)path
|
{
|
return [self readFileAtPathAsString:path error:nil];
|
}
|
|
|
+(NSString *)readFileAtPath:(NSString *)path error:(NSError **)error
|
{
|
return [self readFileAtPathAsString:path error:error];
|
}
|
|
|
+(NSArray *)readFileAtPathAsArray:(NSString *)path
|
{
|
return [NSArray arrayWithContentsOfFile:[self absolutePath:path]];
|
}
|
|
|
+(NSObject *)readFileAtPathAsCustomModel:(NSString *)path
|
{
|
return [NSKeyedUnarchiver unarchiveObjectWithFile:[self absolutePath:path]];
|
}
|
|
|
+(NSData *)readFileAtPathAsData:(NSString *)path
|
{
|
return [self readFileAtPathAsData:path error:nil];
|
}
|
|
|
+(NSData *)readFileAtPathAsData:(NSString *)path error:(NSError **)error
|
{
|
return [NSData dataWithContentsOfFile:[self absolutePath:path] options:NSDataReadingMapped error:error];
|
}
|
|
|
+(NSDictionary *)readFileAtPathAsDictionary:(NSString *)path
|
{
|
return [NSDictionary dictionaryWithContentsOfFile:[self absolutePath:path]];
|
}
|
|
|
+(UIImage *)readFileAtPathAsImage:(NSString *)path
|
{
|
return [self readFileAtPathAsImage:path error:nil];
|
}
|
|
|
+(UIImage *)readFileAtPathAsImage:(NSString *)path error:(NSError **)error
|
{
|
NSData *data = [self readFileAtPathAsData:path error:error];
|
|
if([self isNotError:error])
|
{
|
return [UIImage imageWithData:data];
|
}
|
|
return nil;
|
}
|
|
|
+(UIImageView *)readFileAtPathAsImageView:(NSString *)path
|
{
|
return [self readFileAtPathAsImageView:path error:nil];
|
}
|
|
|
+(UIImageView *)readFileAtPathAsImageView:(NSString *)path error:(NSError **)error
|
{
|
UIImage *image = [self readFileAtPathAsImage:path error:error];
|
|
if([self isNotError:error])
|
{
|
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
|
[imageView sizeToFit];
|
return imageView;
|
}
|
|
return nil;
|
}
|
|
|
+(NSJSONSerialization *)readFileAtPathAsJSON:(NSString *)path
|
{
|
return [self readFileAtPathAsJSON:path error:nil];
|
}
|
|
|
+(NSJSONSerialization *)readFileAtPathAsJSON:(NSString *)path error:(NSError **)error
|
{
|
NSData *data = [self readFileAtPathAsData:path error:error];
|
|
if([self isNotError:error])
|
{
|
NSJSONSerialization *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:error];
|
|
if([NSJSONSerialization isValidJSONObject:json])
|
{
|
return json;
|
}
|
}
|
|
return nil;
|
}
|
|
|
+(NSMutableArray *)readFileAtPathAsMutableArray:(NSString *)path
|
{
|
return [NSMutableArray arrayWithContentsOfFile:[self absolutePath:path]];
|
}
|
|
|
+(NSMutableData *)readFileAtPathAsMutableData:(NSString *)path
|
{
|
return [self readFileAtPathAsMutableData:path error:nil];
|
}
|
|
|
+(NSMutableData *)readFileAtPathAsMutableData:(NSString *)path error:(NSError **)error
|
{
|
return [NSMutableData dataWithContentsOfFile:[self absolutePath:path] options:NSDataReadingMapped error:error];
|
}
|
|
|
+(NSMutableDictionary *)readFileAtPathAsMutableDictionary:(NSString *)path
|
{
|
return [NSMutableDictionary dictionaryWithContentsOfFile:[self absolutePath:path]];
|
}
|
|
|
+(NSString *)readFileAtPathAsString:(NSString *)path
|
{
|
return [self readFileAtPath:path error:nil];
|
}
|
|
|
+(NSString *)readFileAtPathAsString:(NSString *)path error:(NSError **)error
|
{
|
return [NSString stringWithContentsOfFile:[self absolutePath:path] encoding:NSUTF8StringEncoding error:error];
|
}
|
|
|
+(BOOL)removeFilesInDirectoryAtPath:(NSString *)path
|
{
|
return [self removeItemsAtPaths:[self listFilesInDirectoryAtPath:path] error:nil];
|
}
|
|
|
+(BOOL)removeFilesInDirectoryAtPath:(NSString *)path error:(NSError **)error
|
{
|
return [self removeItemsAtPaths:[self listFilesInDirectoryAtPath:path] error:error];
|
}
|
|
|
+(BOOL)removeFilesInDirectoryAtPath:(NSString *)path withExtension:(NSString *)extension
|
{
|
return [self removeItemsAtPaths:[self listFilesInDirectoryAtPath:path withExtension:extension] error:nil];
|
}
|
|
|
+(BOOL)removeFilesInDirectoryAtPath:(NSString *)path withExtension:(NSString *)extension error:(NSError **)error
|
{
|
return [self removeItemsAtPaths:[self listFilesInDirectoryAtPath:path withExtension:extension] error:error];
|
}
|
|
|
+(BOOL)removeFilesInDirectoryAtPath:(NSString *)path withPrefix:(NSString *)prefix
|
{
|
return [self removeItemsAtPaths:[self listFilesInDirectoryAtPath:path withPrefix:prefix] error:nil];
|
}
|
|
|
+(BOOL)removeFilesInDirectoryAtPath:(NSString *)path withPrefix:(NSString *)prefix error:(NSError **)error
|
{
|
return [self removeItemsAtPaths:[self listFilesInDirectoryAtPath:path withPrefix:prefix] error:error];
|
}
|
|
|
+(BOOL)removeFilesInDirectoryAtPath:(NSString *)path withSuffix:(NSString *)suffix
|
{
|
return [self removeItemsAtPaths:[self listFilesInDirectoryAtPath:path withSuffix:suffix] error:nil];
|
}
|
|
|
+(BOOL)removeFilesInDirectoryAtPath:(NSString *)path withSuffix:(NSString *)suffix error:(NSError **)error
|
{
|
return [self removeItemsAtPaths:[self listFilesInDirectoryAtPath:path withSuffix:suffix] error:error];
|
}
|
|
|
+(BOOL)removeItemsInDirectoryAtPath:(NSString *)path
|
{
|
return [self removeItemsInDirectoryAtPath:path error:nil];
|
}
|
|
|
+(BOOL)removeItemsInDirectoryAtPath:(NSString *)path error:(NSError **)error
|
{
|
return [self removeItemsAtPaths:[self listItemsInDirectoryAtPath:path deep:NO] error:error];
|
}
|
|
|
+(BOOL)removeItemAtPath:(NSString *)path
|
{
|
return [self removeItemAtPath:path error:nil];
|
}
|
|
|
+(BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
return [[NSFileManager defaultManager] removeItemAtPath:[self absolutePath:path] error:error];
|
}
|
|
|
+(BOOL)removeItemsAtPaths:(NSArray *)paths
|
{
|
return [self removeItemsAtPaths:paths error:nil];
|
}
|
|
|
+(BOOL)removeItemsAtPaths:(NSArray *)paths error:(NSError **)error
|
{
|
BOOL success = YES;
|
|
for(NSString *path in paths)
|
{
|
success &= [self removeItemAtPath:[self absolutePath:path] error:error];
|
}
|
|
return success;
|
}
|
|
|
+(BOOL)renameItemAtPath:(NSString *)path withName:(NSString *)name
|
{
|
return [self renameItemAtPath:path withName:name error:nil];
|
}
|
|
|
+(BOOL)renameItemAtPath:(NSString *)path withName:(NSString *)name error:(NSError **)error
|
{
|
NSRange indexOfSlash = [name rangeOfString:@"/"];
|
|
if(indexOfSlash.location < name.length)
|
{
|
[NSException raise:@"Invalid name" format:@"file name can't contain a '/'."];
|
|
return NO;
|
}
|
|
return [self moveItemAtPath:path toPath:[[[self absolutePath:path] stringByDeletingLastPathComponent] stringByAppendingPathComponent:name] error:error];
|
}
|
|
|
+(NSString *)sizeFormatted:(NSNumber *)size
|
{
|
double convertedValue = [size doubleValue];
|
int multiplyFactor = 0;
|
|
NSArray *tokens = @[@"bytes", @"KB", @"MB", @"GB", @"TB"];
|
|
while(convertedValue > 1024){
|
convertedValue /= 1024;
|
|
multiplyFactor++;
|
}
|
|
NSString *sizeFormat = ((multiplyFactor > 1) ? @"%4.2f %@" : @"%4.0f %@");
|
|
return [NSString stringWithFormat:sizeFormat, convertedValue, tokens[multiplyFactor]];
|
}
|
|
|
+(NSString *)sizeFormattedOfDirectoryAtPath:(NSString *)path
|
{
|
return [self sizeFormattedOfDirectoryAtPath:path error:nil];
|
}
|
|
|
+(NSString *)sizeFormattedOfDirectoryAtPath:(NSString *)path error:(NSError **)error
|
{
|
NSNumber *size = [self sizeOfDirectoryAtPath:path error:error];
|
|
if(size != nil && [self isNotError:error])
|
{
|
return [self sizeFormatted:size];
|
}
|
|
return nil;
|
}
|
|
|
+(NSString *)sizeFormattedOfFileAtPath:(NSString *)path
|
{
|
return [self sizeFormattedOfFileAtPath:path error:nil];
|
}
|
|
|
+(NSString *)sizeFormattedOfFileAtPath:(NSString *)path error:(NSError **)error
|
{
|
NSNumber *size = [self sizeOfFileAtPath:path error:error];
|
|
if(size != nil && [self isNotError:error])
|
{
|
return [self sizeFormatted:size];
|
}
|
|
return nil;
|
}
|
|
|
+(NSString *)sizeFormattedOfItemAtPath:(NSString *)path
|
{
|
return [self sizeFormattedOfItemAtPath:path error:nil];
|
}
|
|
|
+(NSString *)sizeFormattedOfItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
NSNumber *size = [self sizeOfItemAtPath:path error:error];
|
|
if(size != nil && [self isNotError:error])
|
{
|
return [self sizeFormatted:size];
|
}
|
|
return nil;
|
}
|
|
|
+(NSNumber *)sizeOfDirectoryAtPath:(NSString *)path
|
{
|
return [self sizeOfDirectoryAtPath:path error:nil];
|
}
|
|
|
+(NSNumber *)sizeOfDirectoryAtPath:(NSString *)path error:(NSError **)error
|
{
|
if([self isDirectoryItemAtPath:path error:error])
|
{
|
if([self isNotError:error])
|
{
|
NSNumber *size = [self sizeOfItemAtPath:path error:error];
|
double sizeValue = [size doubleValue];
|
|
if([self isNotError:error])
|
{
|
NSArray *subpaths = [self listItemsInDirectoryAtPath:path deep:YES];
|
NSUInteger subpathsCount = [subpaths count];
|
|
for(NSUInteger i = 0; i < subpathsCount; i++)
|
{
|
NSString *subpath = [subpaths objectAtIndex:i];
|
NSNumber *subpathSize = [self sizeOfItemAtPath:subpath error:error];
|
|
if([self isNotError:error])
|
{
|
sizeValue += [subpathSize doubleValue];
|
}
|
else {
|
return nil;
|
}
|
}
|
|
return [NSNumber numberWithDouble:sizeValue];
|
}
|
}
|
}
|
|
return nil;
|
}
|
|
|
+(NSNumber *)sizeOfFileAtPath:(NSString *)path
|
{
|
return [self sizeOfFileAtPath:path error:nil];
|
}
|
|
|
+(NSNumber *)sizeOfFileAtPath:(NSString *)path error:(NSError **)error
|
{
|
if([self isFileItemAtPath:path error:error])
|
{
|
if([self isNotError:error])
|
{
|
return [self sizeOfItemAtPath:path error:error];
|
}
|
}
|
|
return nil;
|
}
|
|
|
+(NSNumber *)sizeOfItemAtPath:(NSString *)path
|
{
|
return [self sizeOfItemAtPath:path error:nil];
|
}
|
|
|
+(NSNumber *)sizeOfItemAtPath:(NSString *)path error:(NSError **)error
|
{
|
return (NSNumber *)[self attributeOfItemAtPath:path forKey:NSFileSize error:error];
|
}
|
|
|
+(NSURL *)urlForItemAtPath:(NSString *)path
|
{
|
return [NSURL fileURLWithPath:[self absolutePath:path]];
|
}
|
|
|
+(BOOL)writeFileAtPath:(NSString *)path content:(NSObject *)content
|
{
|
return [self writeFileAtPath:path content:content error:nil];
|
}
|
|
|
+(BOOL)writeFileAtPath:(NSString *)path content:(NSObject *)content error:(NSError **)error
|
{
|
if(content == nil)
|
{
|
[NSException raise:@"Invalid content" format:@"content can't be nil."];
|
}
|
|
[self createFileAtPath:path withContent:nil overwrite:YES error:error];
|
|
NSString *absolutePath = [self absolutePath:path];
|
|
if([content isKindOfClass:[NSMutableArray class]])
|
{
|
[((NSMutableArray *)content) writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[NSArray class]])
|
{
|
[((NSArray *)content) writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[NSMutableData class]])
|
{
|
[((NSMutableData *)content) writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[NSData class]])
|
{
|
[((NSData *)content) writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[NSMutableDictionary class]])
|
{
|
[((NSMutableDictionary *)content) writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[NSDictionary class]])
|
{
|
[((NSDictionary *)content) writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[NSJSONSerialization class]])
|
{
|
[((NSDictionary *)content) writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[NSMutableString class]])
|
{
|
[[((NSString *)content) dataUsingEncoding:NSUTF8StringEncoding] writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[NSString class]])
|
{
|
[[((NSString *)content) dataUsingEncoding:NSUTF8StringEncoding] writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[UIImage class]])
|
{
|
[UIImagePNGRepresentation((UIImage *)content) writeToFile:absolutePath atomically:YES];
|
}
|
else if([content isKindOfClass:[UIImageView class]])
|
{
|
return [self writeFileAtPath:absolutePath content:((UIImageView *)content).image error:error];
|
}
|
else if([content conformsToProtocol:@protocol(NSCoding)])
|
{
|
[NSKeyedArchiver archiveRootObject:content toFile:absolutePath];
|
}
|
else {
|
[NSException raise:@"Invalid content type" format:@"content of type %@ is not handled.", NSStringFromClass([content class])];
|
|
return NO;
|
}
|
|
return YES;
|
}
|
|
|
+(NSDictionary *)metadataOfImageAtPath:(NSString *)path
|
{
|
if([self isFileItemAtPath:path])
|
{
|
//http://blog.depicus.com/getting-exif-data-from-images-on-ios/
|
|
NSURL *url = [self urlForItemAtPath:path];
|
CGImageSourceRef sourceRef = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
|
NSDictionary *metadata = (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(sourceRef, 0, NULL));
|
|
return metadata;
|
}
|
|
return nil;
|
}
|
|
|
+(NSDictionary *)exifDataOfImageAtPath:(NSString *)path
|
{
|
NSDictionary *metadata = [self metadataOfImageAtPath:path];
|
|
if(metadata)
|
{
|
return [metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary];
|
}
|
|
return nil;
|
}
|
|
|
+(NSDictionary *)tiffDataOfImageAtPath:(NSString *)path
|
{
|
NSDictionary *metadata = [self metadataOfImageAtPath:path];
|
|
if(metadata)
|
{
|
return [metadata objectForKey:(NSString *)kCGImagePropertyTIFFDictionary];
|
}
|
|
return nil;
|
}
|
|
|
+(NSDictionary *)xattrOfItemAtPath:(NSString *)path
|
{
|
NSMutableDictionary *values = [[NSMutableDictionary alloc] init];
|
|
const char *upath = [path UTF8String];
|
|
ssize_t ukeysSize = listxattr(upath, NULL, 0, 0);
|
|
if( ukeysSize > 0 )
|
{
|
char *ukeys = malloc(ukeysSize);
|
|
ukeysSize = listxattr(upath, ukeys, ukeysSize, 0);
|
|
NSUInteger keyOffset = 0;
|
NSString *key;
|
NSString *value;
|
|
while(keyOffset < ukeysSize)
|
{
|
key = [NSString stringWithUTF8String:(keyOffset + ukeys)];
|
keyOffset += ([key length] + 1);
|
|
value = [self xattrOfItemAtPath:path getValueForKey:key];
|
[values setObject:value forKey:key];
|
}
|
|
free(ukeys);
|
}
|
|
return [NSDictionary dictionaryWithObjects:[values allValues] forKeys:[values allKeys]];
|
}
|
|
|
+(NSString *)xattrOfItemAtPath:(NSString *)path getValueForKey:(NSString *)key
|
{
|
NSString *value = nil;
|
|
const char *ukey = [key UTF8String];
|
const char *upath = [path UTF8String];
|
|
ssize_t uvalueSize = getxattr(upath, ukey, NULL, 0, 0, 0);
|
|
if( uvalueSize > -1 )
|
{
|
if( uvalueSize == 0 )
|
{
|
value = @"";
|
}
|
else {
|
|
char *uvalue = malloc(uvalueSize);
|
|
if( uvalue )
|
{
|
getxattr(upath, ukey, uvalue, uvalueSize, 0, 0);
|
uvalue[uvalueSize] = '\0';
|
value = [NSString stringWithUTF8String:uvalue];
|
free(uvalue);
|
}
|
}
|
}
|
|
return value;
|
}
|
|
|
+(BOOL)xattrOfItemAtPath:(NSString *)path hasValueForKey:(NSString *)key
|
{
|
return ([self xattrOfItemAtPath:path getValueForKey:key] != nil);
|
}
|
|
|
+(BOOL)xattrOfItemAtPath:(NSString *)path removeValueForKey:(NSString *)key
|
{
|
int result = removexattr([path UTF8String], [key UTF8String], 0);
|
|
return (result == 0);
|
}
|
|
|
+(BOOL)xattrOfItemAtPath:(NSString *)path setValue:(NSString *)value forKey:(NSString *)key
|
{
|
if(value == nil)
|
{
|
return NO;
|
}
|
|
int result = setxattr([path UTF8String], [key UTF8String], [value UTF8String], [value length], 0, 0);
|
|
return (result == 0);
|
}
|
|
|
@end
|