zoukankan      html  css  js  c++  java
  • 计算缓存文件大小

    项目中碰到一个需要计算沙盒目录的大小的功能。

    看了下NSFileManager提供的方法,找到一个

    - (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0);


    经过测试发现这个方法只能计算文件的大小,而不能直接计算文件夹的大小;

    发现这个问题,解决方法只有一种方法了,就是递归便利目录累加所有的文件;

    本来气势冲冲的写了一半了,突然发现

    - (NSArray *)subpathsAtPath:(NSString *)path;


    这个方法居然会返回子目录中所有文件的相对路径!!

    哎哟我勒个去,这样就不要写递归了,直接拼接上相对路径,直接就能够拿到你想要的绝对路径了!!

    这样计算一个目录的大小就只用写一个while就可以了

    +(NSString*)getCacheSize{        
    	NSDate* begin = [NSDate date];    
    	NSFileManager* fm = [NSFileManager defaultManager];    
    	__block NSError* error = nil;        
    	__block NSUInteger fileSize = 0;            
    	//获取Books的缓存    
    	dispatch_sync(queue, ^{        
    		NSArray* subFiles = [fm subpathsAtPath:BOOKHEADERPath([LoginPlugin share].userID)];        
    		NSLog(@"subpath = %@",subFiles);        
    		for (NSString* fileName in subFiles) {            
    			if ([fileName hasSuffix:@"png"]||[fileName hasSuffix:@"jpg"]) {                
    				NSDictionary* dic = [fm attributesOfItemAtPath:BOOKPATH([LoginPlugin share].userID,fileName) error:&error];                		NSUInteger size = (error ? 0:[dic fileSize]);                
    				fileSize += size;            
    			}        
    		}    
    	});            
    	NSString* cacheString = [NSString stringWithFormat:@"%.1fM",fileSize/(1024.0*1024)];    
    	NSTimeInterval time = [begin timeIntervalSinceNow];    
    	NSLog(@"便利文件耗费时间:%lf",time/60.0);    
    	return cacheString;
    }


    不要担心便利太多文件会影响效率,系统便利10M的文件仅耗费了0.00025S。这个也不是绝对的,需要自己亲自调试了

    在我的项目还有另一个问题,我要统计缓存,因为我用了SDWebImage,所以要整合我自己下载的图书还有SDImageCache;

    查看了下SDImageCache的代码,其中提供了一个方法:

    - (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock;


    内部实现是在一个串行的queue中便利,然后通过block回调。

    但是如果碰到我上边写的代码有个返回值的,就有问题了。

    因为我不可能在Block里边return size;

    这个如何是好,着实让人欢喜让人忧

    哈哈,这个时候解决办法就是获取SDImageCache的queue,然后在它执行完自己的计算task之后,同步调用阻塞主线程,这样就可以不需要修改代码了

    为毛这样可以捏?因为这个queue是串行的,哇哈哈!!!

    方法如下:

    +(NSString*)getCacheSize{        
    	NSDate* begin = [NSDate date];    
    	SDImageCache* imageCache = [[SDWebImageManager sharedManager] imageCache];    
    	dispatch_queue_t queue =imageCache .ioQueue;     
    	NSFileManager* fm = [NSFileManager defaultManager];    
    	__block NSError* error = nil;        
    	__block NSUInteger fileSize = 0;        
    	//获取SD的缓存    
    	[imageCache calculateSizeWithCompletionBlock:^(NSUInteger fileCount, NSUInteger totalSize) {        
    		fileSize += totalSize;    }];        
    		//获取Books的缓存    
    		dispatch_sync(queue, ^{        
    			NSArray* subFiles = [fm subpathsAtPath:BOOKHEADERPath([LoginPlugin share].userID)];        
    			NSLog(@"subpath = %@",subFiles);        
    			for (NSString* fileName in subFiles) {            
    				if ([fileName hasSuffix:@"png"]||[fileName hasSuffix:@"jpg"]) {                
    					NSDictionary* dic = [fm attributesOfItemAtPath:BOOKPATH([LoginPlugin share].userID,fileName) error:&error];                
    					NSUInteger size = (error ? 0:[dic fileSize]);                
    					fileSize += size;            
    				}        
    			}    
    		});            
    		NSString* cacheString = [NSString stringWithFormat:@"%.1fM",fileSize/(1024.0*1024)];    
    		NSTimeInterval time = [begin timeIntervalSinceNow];    
    		NSLog(@"便利文件耗费时间:%lf",time/60.0);    
    		return cacheString;
    	}



    妥妥的,因为是个类方法,就不提供源代码鸟!只需要替换下测试路径就OK了!

  • 相关阅读:
    POJ2155 Matrix 【二维线段树】
    BZOJ4785 [Zjoi2017]树状数组 【二维线段树 + 标记永久化】
    B1027 打印沙漏
    Tomcat无法成功启动——双击startup.bat闪退
    MySQL在cmd命令行查看端口号
    1009 说反话(类似回文字符串)
    除基取余法,
    日期差值
    怎么把VS里的scanf_s换成scanf
    联想小新潮怎么修改fn热键以及怎么进入bios状态
  • 原文地址:https://www.cnblogs.com/luseike/p/4251000.html
Copyright © 2011-2022 走看看