You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
3.7 KiB

  1. //
  2. // FLEXFileBrowserSearchOperation.m
  3. // FLEX
  4. //
  5. // Created by 啟倫 陳 on 2014/8/4.
  6. // Copyright (c) 2014f. All rights reserved.
  7. //
  8. #import "FLEXFileBrowserSearchOperation.h"
  9. @implementation NSMutableArray (FLEXStack)
  10. - (void)flex_push:(id)anObject
  11. {
  12. [self addObject:anObject];
  13. }
  14. - (id)flex_pop
  15. {
  16. id anObject = [self lastObject];
  17. [self removeLastObject];
  18. return anObject;
  19. }
  20. @end
  21. @interface FLEXFileBrowserSearchOperation ()
  22. @property (nonatomic, strong) NSString *path;
  23. @property (nonatomic, strong) NSString *searchString;
  24. @end
  25. @implementation FLEXFileBrowserSearchOperation
  26. #pragma mark - private
  27. - (uint64_t)totalSizeAtPath:(NSString *)path
  28. {
  29. NSFileManager *fileManager = [NSFileManager defaultManager];
  30. NSDictionary<NSString *, id> *attributes = [fileManager attributesOfItemAtPath:path error:NULL];
  31. uint64_t totalSize = [attributes fileSize];
  32. for (NSString *fileName in [fileManager enumeratorAtPath:path]) {
  33. attributes = [fileManager attributesOfItemAtPath:[path stringByAppendingPathComponent:fileName] error:NULL];
  34. totalSize += [attributes fileSize];
  35. }
  36. return totalSize;
  37. }
  38. #pragma mark - instance method
  39. - (id)initWithPath:(NSString *)currentPath searchString:(NSString *)searchString
  40. {
  41. self = [super init];
  42. if (self) {
  43. self.path = currentPath;
  44. self.searchString = searchString;
  45. }
  46. return self;
  47. }
  48. #pragma mark - methods to override
  49. - (void)main
  50. {
  51. NSFileManager *fileManager = [NSFileManager defaultManager];
  52. NSMutableArray<NSString *> *searchPaths = [NSMutableArray array];
  53. NSMutableDictionary<NSString *, NSNumber *> *sizeMapping = [NSMutableDictionary dictionary];
  54. uint64_t totalSize = 0;
  55. NSMutableArray<NSString *> *stack = [NSMutableArray array];
  56. [stack flex_push:self.path];
  57. //recursive found all match searchString paths, and precomputing there size
  58. while ([stack count]) {
  59. NSString *currentPath = [stack flex_pop];
  60. NSArray<NSString *> *directoryPath = [fileManager contentsOfDirectoryAtPath:currentPath error:nil];
  61. for (NSString *subPath in directoryPath) {
  62. NSString *fullPath = [currentPath stringByAppendingPathComponent:subPath];
  63. if ([[subPath lowercaseString] rangeOfString:[self.searchString lowercaseString]].location != NSNotFound) {
  64. [searchPaths addObject:fullPath];
  65. if (!sizeMapping[fullPath]) {
  66. uint64_t fullPathSize = [self totalSizeAtPath:fullPath];
  67. totalSize += fullPathSize;
  68. [sizeMapping setObject:@(fullPathSize) forKey:fullPath];
  69. }
  70. }
  71. BOOL isDirectory;
  72. if ([fileManager fileExistsAtPath:fullPath isDirectory:&isDirectory] && isDirectory) {
  73. [stack flex_push:fullPath];
  74. }
  75. if ([self isCancelled]) {
  76. return;
  77. }
  78. }
  79. }
  80. //sort
  81. NSArray<NSString *> *sortedArray = [searchPaths sortedArrayUsingComparator:^NSComparisonResult(NSString *path1, NSString *path2) {
  82. uint64_t pathSize1 = [sizeMapping[path1] unsignedLongLongValue];
  83. uint64_t pathSize2 = [sizeMapping[path2] unsignedLongLongValue];
  84. if (pathSize1 < pathSize2) {
  85. return NSOrderedAscending;
  86. } else if (pathSize1 > pathSize2) {
  87. return NSOrderedDescending;
  88. } else {
  89. return NSOrderedSame;
  90. }
  91. }];
  92. if ([self isCancelled]) {
  93. return;
  94. }
  95. dispatch_async(dispatch_get_main_queue(), ^{
  96. [self.delegate fileBrowserSearchOperationResult:sortedArray size:totalSize];
  97. });
  98. }
  99. @end