Obtener el contenido del directorio en orden modificada fecha
-
19-09-2019 - |
Pregunta
¿Hay un método para obtener el contenido de una carpeta en un orden determinado? Me gustaría una serie de diccionarios de atributos de archivo (o simplemente los nombres de archivo) ordenados por fecha de modificación.
En este momento, estoy haciendo de esta manera:
- obtener una matriz con los nombres de los archivos
- obtener los atributos de cada archivo
- almacenar la ruta del archivo y la fecha de modificación en un diccionario con la fecha como una clave
A continuación tengo para dar salida al diccionario en orden cronológico, pero me preguntaba si hay una manera más fácil? Si no, ¿hay algún lugar un fragmento de código que hacer esto por mí?
Gracias.
Solución
Código de nall anterior me señaló en la dirección correcta, pero creo que hay algunos errores en el código tal como fue anunciado anteriormente. Por ejemplo:
-
¿Por qué es
filesAndProperties
asignada usandoNMutableDictonary
en lugar de unNSMutableArray
? -
El código anterior se pasa el parámetro incorrecto paraNSDictionary* properties = [[NSFileManager defaultManager] attributesOfItemAtPath:NSFileModificationDate error:&error];
attributesOfItemAtPath
- cabeattributesOfItemAtPath:path
-
Su está ordenando la matriz
files
, pero debe ser la clasificaciónfilesAndProperties
.
He implementado el mismo, con las correcciones, y el uso de bloques y publicado a continuación:
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsPath = [searchPaths objectAtIndex: 0];
NSError* error = nil;
NSArray* filesArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsPath error:&error];
if(error != nil) {
NSLog(@"Error in reading files: %@", [error localizedDescription]);
return;
}
// sort by creation date
NSMutableArray* filesAndProperties = [NSMutableArray arrayWithCapacity:[filesArray count]];
for(NSString* file in filesArray) {
NSString* filePath = [iMgr.documentsPath stringByAppendingPathComponent:file];
NSDictionary* properties = [[NSFileManager defaultManager]
attributesOfItemAtPath:filePath
error:&error];
NSDate* modDate = [properties objectForKey:NSFileModificationDate];
if(error == nil)
{
[filesAndProperties addObject:[NSDictionary dictionaryWithObjectsAndKeys:
file, @"path",
modDate, @"lastModDate",
nil]];
}
}
// sort using a block
// order inverted as we want latest date first
NSArray* sortedFiles = [filesAndProperties sortedArrayUsingComparator:
^(id path1, id path2)
{
// compare
NSComparisonResult comp = [[path1 objectForKey:@"lastModDate"] compare:
[path2 objectForKey:@"lastModDate"]];
// invert ordering
if (comp == NSOrderedDescending) {
comp = NSOrderedAscending;
}
else if(comp == NSOrderedAscending){
comp = NSOrderedDescending;
}
return comp;
}];
Otros consejos
¿Qué tal esto:
// Application documents directory
NSURL *documentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:documentsURL
includingPropertiesForKeys:@[NSURLContentModificationDateKey]
options:NSDirectoryEnumerationSkipsHiddenFiles
error:nil];
NSArray *sortedContent = [directoryContent sortedArrayUsingComparator:
^(NSURL *file1, NSURL *file2)
{
// compare
NSDate *file1Date;
[file1 getResourceValue:&file1Date forKey:NSURLContentModificationDateKey error:nil];
NSDate *file2Date;
[file2 getResourceValue:&file2Date forKey:NSURLContentModificationDateKey error:nil];
// Ascending:
return [file1Date compare: file2Date];
// Descending:
//return [file2Date compare: file1Date];
}];
Más simple ...
NSArray* filelist_sorted;
filelist_sorted = [filelist_raw sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDictionary* first_properties = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@", path_thumb, obj1] error:nil];
NSDate* first = [first_properties objectForKey:NSFileModificationDate];
NSDictionary* second_properties = [[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@", path_thumb, obj2] error:nil];
NSDate* second = [second_properties objectForKey:NSFileModificationDate];
return [second compare:first];
}];
Es demasiado lento
[[NSFileManager defaultManager]
attributesOfItemAtPath:NSFileModificationDate
error:&error];
Prueba este código:
+ (NSDate*) getModificationDateForFileAtPath:(NSString*)path {
struct tm* date; // create a time structure
struct stat attrib; // create a file attribute structure
stat([path UTF8String], &attrib); // get the attributes of afile.txt
date = gmtime(&(attrib.st_mtime)); // Get the last modified time and put it into the time structure
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setSecond: date->tm_sec];
[comps setMinute: date->tm_min];
[comps setHour: date->tm_hour];
[comps setDay: date->tm_mday];
[comps setMonth: date->tm_mon + 1];
[comps setYear: date->tm_year + 1900];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *modificationDate = [[cal dateFromComponents:comps] addTimeInterval:[[NSTimeZone systemTimeZone] secondsFromGMT]];
[comps release];
return modificationDate;
}
El código no funciona en el iPhone SDK, lleno de error de compilación. Por favor, encontrar el código actualizado `
NSInteger lastModifiedSort(id path1, id path2, void* context)
{
int comp = [[path1 objectForKey:@"lastModDate"] compare:
[path2 objectForKey:@"lastModDate"]];
return comp;
}
-(NSArray *)filesByModDate:(NSString*) path{
NSError* error = nil;
NSArray* filesArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path
error:&error];
if(error == nil)
{
NSMutableArray* filesAndProperties = [NSMutableArray arrayWithCapacity:[filesArray count]];
for(NSString* imgName in filesArray)
{
NSString *imgPath = [NSString stringWithFormat:@"%@/%@",path,imgName];
NSDictionary* properties = [[NSFileManager defaultManager]
attributesOfItemAtPath:imgPath
error:&error];
NSDate* modDate = [properties objectForKey:NSFileModificationDate];
if(error == nil)
{
[filesAndProperties addObject:[NSDictionary dictionaryWithObjectsAndKeys:
imgName, @"path",
modDate, @"lastModDate",
nil]];
}else{
NSLog(@"%@",[error description]);
}
}
NSArray* sortedFiles = [filesAndProperties sortedArrayUsingFunction:&lastModifiedSort context:nil];
NSLog(@"sortedFiles: %@", sortedFiles);
return sortedFiles;
}
else
{
NSLog(@"Encountered error while accessing contents of %@: %@", path, error);
}
return filesArray;
}
`