2009-10-06 117 views
33

是否有一種方法以特定順序獲取文件夾的內容?我想要修改日期排序的文件屬性字典數組(或只是文件名)。以修改日期的順序獲取目錄內容

現在,我在做這樣說:

  • 獲得與文件名
  • 陣列獲取的每個文件
  • 店該文件的路徑的屬性和修改日期在字典以日期爲關鍵字

接下來我必須按日期順序輸出字典,但我想知道是否有更簡單的方法?如果沒有,是否有代碼片段可以爲我做到這一點?

謝謝。

回答

35

上述NALL的代碼我指出了正確的方向,但我認爲在上面發佈的代碼中存在一些錯誤。例如:

  1. 爲什麼filesAndProperties使用NMutableDictonary而非NSMutableArray分配呢?

  2. 
    NSDictionary* properties = [[NSFileManager defaultManager] 
                 attributesOfItemAtPath:NSFileModificationDate 
                 error:&error]; 
    
    
    上面的代碼傳遞錯誤的參數attributesOfItemAtPath - 它應該是attributesOfItemAtPath:path

  3. 您正在分揀files數組,但你應該排序filesAndProperties


我已經實現了一樣,用改正,並使用模塊和貼在下面:


    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

要反轉排序,您可以將比較結果乘以-1。 – 2011-10-01 14:01:58

+5

要顛倒順序,你可以使用'return [[path2 objectForKey:@「lastModDate」] compare:[path1 objectForKey:@「lastModDate」]];' – Ievgen 2012-01-06 15:44:42

0

代碼在iPhone SDK中不起作用,充滿了編譯錯誤。請找到更新的代碼 `

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

感謝您的回答。這裏似乎有一些東西在iPhone SDK中不起作用(NSURLContentModificationDateKey和其他一些NSURL方法)。 – 2009-10-06 07:24:04

+0

我已經開始嘗試將其更改爲使用iPhone SDK,但getResourceValue在那裏不存在。我會爲iPhone尋找一個數組排序。 – 2009-10-06 07:31:22

+0

nevan,我更新了這個在iPhone SDK的約束下工作 – nall 2009-10-06 13:15:51

5

這是太慢

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

試試這個代碼:

+ (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

這要快得多。我的測試速度快4倍。儘管如此,我遇到了一個錯誤。我的gmtime正在返回UTC而不是GMT。有些時候有一個小時的差異導致了問題。 – 2013-10-05 16:33:46

+0

調整代碼如下: NSCalendar * cal = [NSCalendar currentCalendar]; NSTimeZone * tz = [NSTimeZone timeZoneWithAbbreviation:[[NSString alloc] initWithUTF8String:date-> tm_zone]]; cal.timeZone = tz; – 2013-10-05 16:35:26

+0

您需要#import「sys/stat.h」 – 2014-10-09 09:20:37

10

簡單...

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

什麼是path_thumb? – DJTano 2017-11-02 19:05:50

19

這個怎麼樣:

// 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

我只是爲自己尋找解決方案,並最終使用上面的代碼。所以我把它放在這裏,因爲我認爲它比其他人提供的更清潔;) – 2012-11-01 10:48:16