Как получить все пути ресурсов в моем пакете рекурсивно в iOS?
У меня есть "распакованная" папка в моем приложении. Мне нужно получить пути к ресурсам для всех файлов типа txt. Я использовал это,
NSArray *filePaths = [NSBundle pathsForResourcesOfType:@"txt" inDirectory:[[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/unzipped"]];
Но он только получает файлы в первом каталоге. Есть ли рекурсивная версия этого где-то, что я просто отсутствую?
Ответы
Ответ 1
Я получил эту работу, используя код, отправленный @rekle в качестве отправной точки. Хитрость заключается в использовании NSDirectoryEnumerator, который будет делать это рекурсивно. Здесь функция, которую я написал, в случае, если кому-то это нужно.
- (NSArray *)recursivePathsForResourcesOfType:(NSString *)type inDirectory:(NSString *)directoryPath{
NSMutableArray *filePaths = [[NSMutableArray alloc] init];
// Enumerators are recursive
NSDirectoryEnumerator *enumerator = [[[NSFileManager defaultManager] enumeratorAtPath:directoryPath] retain];
NSString *filePath;
while ((filePath = [enumerator nextObject]) != nil){
// If we have the right type of file, add it to the list
// Make sure to prepend the directory path
if([[filePath pathExtension] isEqualToString:type]){
[filePaths addObject:[directoryPath stringByAppendingPathComponent:filePath]];
}
}
[enumerator release];
return [filePaths autorelease];
}
Swift, используя NSURL
func recursivePathsForResources(type type: String) -> [NSURL] {
// Enumerators are recursive
let enumerator = NSFileManager.defaultManager().enumeratorAtPath(bundlePath)
var filePaths = [NSURL]()
while let filePath = enumerator?.nextObject() as? String {
if NSURL(fileURLWithPath: filePath).pathExtension == type {
filePaths.append(bundleURL.URLByAppendingPathComponent(filePath))
}
}
return filePaths
}
Ответ 2
Просто обновите этот метод, чтобы разрешить любые типы файлов (nil) и предоставить правильный формат пути
- (NSArray *)recursivePathsForResourcesOfType:(NSString *)type inDirectory:(NSString *)directoryPath{
NSMutableArray *filePaths = [[NSMutableArray alloc] init];
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:directoryPath];
NSString *filePath;
while ((filePath = [enumerator nextObject]) != nil){
if (!type || [[filePath pathExtension] isEqualToString:type]){
[filePaths addObject:[directoryPath stringByAppendingPathComponent:filePath]];
}
}
return filePaths;
}
Ответ 3
Попробуйте что-то вроде этого:
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSError *error = nil;
NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundlePath error:&error];
'files' будет массивом строк, содержащих все имена файлов в этом пути...
Ответ 4
Swift 3.1 версия ответа от smokinggoyster
func recursivePathsForResources(type: String, in directoryPath: String) -> [String] {
// Enumerators are recursive
let enumerator = FileManager.default.enumerator(atPath: directoryPath)
var filePaths: [String] = []
while let filePath = enumerator?.nextObject() as? String {
if URL(fileURLWithPath: filePath).pathExtension == type {
filePaths.append(directoryPath.byAppending(pathComponent: filePath))
}
}
return filePaths
}
Ответ 5
Перед копированием подумайте о создании символической ссылки. Вы можете создать символическую ссылку одна в папку с большим количеством элементов.
И он будет работать в большинстве ситуаций.
Вы не сможете создавать другой поток, ожидая окончания работы и т.д.