iphone - txt - Obtener una lista de archivos en un directorio con un glob
obtener listado de archivos de una carpeta (8)
¿Qué hay de usar los métodos hasSuffix y hasPrefix de NSString? Algo así como (si estás buscando "foo * .jpg"):
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *dirContents = [[NSFileManager defaultManager] directoryContentsAtPath:bundleRoot];
for (NSString *tString in dirContents) {
if ([tString hasPrefix:@"foo"] && [tString hasSuffix:@".jpg"]) {
// do stuff
}
}
Para coincidencias sencillas y directas como esa, sería más simple que usar una biblioteca de expresiones regulares.
Por algún motivo loco, no puedo encontrar una forma de obtener una lista de archivos con un glob para un directorio determinado.
Actualmente estoy atascado con algo parecido a:
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *dirContents = [[NSFileManager defaultManager]
directoryContentsAtPath:bundleRoot];
... y luego quitar las cosas que no quiero, lo cual apesta. Pero lo que realmente me gustaría es poder buscar algo como "foo * .jpg" en lugar de buscar todo el directorio, pero no he podido encontrar nada de eso.
Entonces, ¿cómo diablos lo haces?
Esto funciona muy bien para IOS
, pero también debería funcionar para el cocoa
.
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *manager = [NSFileManager defaultManager];
NSDirectoryEnumerator *direnum = [manager enumeratorAtPath:bundleRoot];
NSString *filename;
while ((filename = [direnum nextObject] )) {
//change the suffix to what you are looking for
if ([filename hasSuffix:@".data"]) {
// Do work here
NSLog(@"Files in resource folder: %@", filename);
}
}
Método más simple:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList = [manager contentsOfDirectoryAtPath:documentsDirectory
error:nil];
//--- Listing file by name sort
NSLog(@"/n File list %@",fileList);
//---- Sorting files by extension
NSArray *filePathsArray =
[[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory
error:nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF EndsWith ''.png''"];
filePathsArray = [filePathsArray filteredArrayUsingPredicate:predicate];
NSLog(@"/n/n Sorted files by extension %@",filePathsArray);
Necesitas rodar tu propio método para eliminar los archivos que no deseas.
Esto no es fácil con las herramientas integradas, pero podría usar RegExKit Lite para ayudarlo a encontrar los elementos en la matriz devuelta que le interese. De acuerdo con las notas de la versión, esto debería funcionar en las aplicaciones Cocoa y Cocoa-Touch.
Aquí está el código de demostración que escribí en unos 10 minutos. Cambié <y> a "porque no se mostraban dentro del bloque pre, pero aún funciona con las comillas. Tal vez alguien que sepa más sobre el código de formato aquí en lo corrija (¿Chris?).
Este es un proyecto de plantilla de la herramienta de línea de comandos de "Herramienta básica". Si obtengo mi git daemon y lo ejecuto en mi servidor doméstico, editaré esta publicación para agregar la URL del proyecto.
#import "Foundation/Foundation.h" #import "RegexKit/RegexKit.h" @interface MTFileMatcher : NSObject { } - (void)getFilesMatchingRegEx:(NSString*)inRegex forPath:(NSString*)inPath; @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // insert code here... MTFileMatcher* matcher = [[[MTFileMatcher alloc] init] autorelease]; [matcher getFilesMatchingRegEx:@"^.+//.[Jj][Pp][Ee]?[Gg]$" forPath:[@"~/Pictures" stringByExpandingTildeInPath]]; [pool drain]; return 0; } @implementation MTFileMatcher - (void)getFilesMatchingRegEx:(NSString*)inRegex forPath:(NSString*)inPath; { NSArray* filesAtPath = [[[NSFileManager defaultManager] directoryContentsAtPath:inPath] arrayByMatchingObjectsWithRegex:inRegex]; NSEnumerator* itr = [filesAtPath objectEnumerator]; NSString* obj; while (obj = [itr nextObject]) { NSLog(obj); } } @end
No voy a pretender ser un experto en el tema, pero debería tener acceso a las funciones glob
y wordexp
-C, ¿no?
Puedes lograr esto bastante fácilmente con la ayuda de NSPredicate, así:
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *dirContents = [fm contentsOfDirectoryAtPath:bundleRoot error:nil];
NSPredicate *fltr = [NSPredicate predicateWithFormat:@"self ENDSWITH ''.jpg''"];
NSArray *onlyJPGs = [dirContents filteredArrayUsingPredicate:fltr];
Si necesita hacerlo con NSURL en su lugar, se ve así:
NSURL *bundleRoot = [[NSBundle mainBundle] bundleURL];
NSArray * dirContents =
[fm contentsOfDirectoryAtURL:bundleRoot
includingPropertiesForKeys:@[]
options:NSDirectoryEnumerationSkipsHiddenFiles
error:nil];
NSPredicate * fltr = [NSPredicate predicateWithFormat:@"pathExtension=''jpg''"];
NSArray * onlyJPGs = [dirContents filteredArrayUsingPredicate:fltr];
Unix tiene una biblioteca que puede realizar operaciones de globbing de archivos para usted. Las funciones y los tipos se declaran en un encabezado llamado glob.h
, por lo que deberá #include
. Si abres una terminal y abres la página man para glob, escribiendo man 3 glob
obtendrás toda la información que necesitas saber para usar las funciones.
A continuación se muestra un ejemplo de cómo se puede poblar una matriz de los archivos que coinciden con un patrón globbing. Al usar la función glob
, hay algunas cosas que debe tener en cuenta.
- Por defecto, la función
glob
busca archivos en el directorio de trabajo actual. Para buscar en otro directorio, deberá anteponer el nombre del directorio al patrón globbing como lo hice en mi ejemplo para obtener todos los archivos en/bin
. - Usted es responsable de limpiar la memoria asignada por
glob
al llamar aglobfree
cuando haya terminado con la estructura.
En mi ejemplo, uso las opciones predeterminadas y no hay devolución de llamada por error. La página man cubre todas las opciones en caso de que haya algo allí que desee utilizar. Si va a utilizar el código anterior, le sugiero que lo agregue como categoría a NSArray
o algo así.
NSMutableArray* files = [NSMutableArray array];
glob_t gt;
char* pattern = "/bin/*";
if (glob(pattern, 0, NULL, >) == 0) {
int i;
for (i=0; i<gt.gl_matchc; i++) {
[files addObject: [NSString stringWithCString: gt.gl_pathv[i]]];
}
}
globfree(>);
return [NSArray arrayWithArray: files];
Editar: He creado un github en github que contiene el código anterior en una categoría llamada NSArray+Globbing .
stringWithFileSystemRepresentation no parece estar disponible en iOS.