2009-10-06 12 views
33

Czy istnieje metoda pobrania zawartości folderu w określonej kolejności? Poproszę o zestaw słowników atrybutów plików (lub po prostu nazw plików) uporządkowanych według daty modyfikacji.Pobieranie zawartości katalogu według daty modyfikacji zamówienia

Teraz robię to w ten sposób:

  • uzyskać tablicę z nazwami plików
  • dostać atrybuty każdego pliku
  • przechowywać ścieżkę do pliku i data modyfikacji w słowniku z datą jako kluczem

Następnie muszę wypisać słownik w porządku daty, ale zastanawiałem się, czy jest łatwiejszy sposób? Jeśli nie, czy jest gdzieś fragment kodu, który zrobi to za mnie?

Dzięki.

Odpowiedz

35

kod nWszystkie za wyżej wskazał mnie we właściwym kierunku, ale Myślę, że w kodzie są błędy, które zostały zamieszczone powyżej. Na przykład:

  1. Dlaczego filesAndProperties przydzielane za pomocą NMutableDictonary raczej niż NSMutableArray?

  2. 
    NSDictionary* properties = [[NSFileManager defaultManager] 
                 attributesOfItemAtPath:NSFileModificationDate 
                 error:&error]; 
    
    
    Powyższy kod przechodzi niewłaściwy parametr dla attributesOfItemAtPath - powinien być attributesOfItemAtPath:path

  3. Twoje są sortowania tablicy files, ale powinno być sortowania filesAndProperties.


I wprowadziły takie same, z poprawkami, a przy użyciu bloków i pisał poniżej:


    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;         
          }]; 

+0

Aby odwrócić kolejność, możesz pomnożyć wynik porównania przez -1. –

+5

Aby odwrócić kolejność, możesz użyć 'return [[ścieżka2 objectForKey: @" lastModDate "] porównaj: [ścieżka1 objectForKey: @" lastModDate "]];' – Ievgen

0

Kod nie działa w iPhone SDK, pełen błąd kompilacji. Proszę znaleźć zaktualizowany kod `

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; 
} 

`

+0

Dzięki za odpowiedź.Wydaje się, że jest kilka rzeczy, które nie będą działać z iPhone SDK tutaj (NSURLContentModificationDateKey i kilka innych metod NSURL). –

+0

Zacząłem próbować zmienić to, aby działało z zestawem SDK iPhone'a, ale getResourceValue tam nie istnieje. Poszukuję sortowania szyku dla iPhone'a. –

+0

nevan, zaktualizowałem to do pracy w ramach ograniczeń iPhone'a SDK – nall

5

Jest zbyt powolny

[[NSFileManager defaultManager] 
           attributesOfItemAtPath:NSFileModificationDate 
           error:&error]; 

Spróbuj kod:

+ (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; 
} 
+0

To znacznie szybciej. 4x szybciej w moich testach. Wpadłem jednak na jeden błąd. Mój gmtime zwraca UTC, a nie GMT. Czasami występowała różnica godzin, która powodowała problemy. –

+0

Dostosuj kod w następujący sposób: NSCalendar * cal = [NSCalendar currentCalendar]; NSTimeZone * tz = [NSTimeZone timeZoneWithAbbreviation: [[NSString alloc] initWithUTF8String: date-> tm_zone]]; cal.timeZone = tz; –

+0

Musisz #import "sys/stat.h" –

10

prostsze ...

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]; 
}]; 
+0

co to ścieżka path_thumb? – DJTano

19

Jak na ten temat :

// 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]; 
         }]; 
+11

Po prostu szukałem rozwiązania dla tego samego i skończyło się na użyciu powyższego kodu. Więc umieściłem to tutaj, ponieważ myślę, że jest czystsze niż to, co inni zapewnili;) –

Powiązane problemy