您的位置:首页 > 移动开发 > IOS开发

iOS NSFileManager管理目录路径(3)——文件大小

2017-06-29 17:07 375 查看
计算文件大小,既可以计算指定文件路径的某个文件大小,也可以计算指定目录的大小,该目录可能包含多个子目录及文件。

1、计算单个文件的大小dobule

+ (BOOL)isFileExists:(NSString *)filepath
{
return [[NSFileManager defaultManager] fileExistsAtPath:filepath];
}

+ (NSDictionary *)fileAttributesWithFilePath:(NSString *)filePath
{
if ([self isFileExists:filePath])
{
return [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
}
return nil;
}

+ (double)fileSizeNumberWithFilePath:(NSString *)filePath
{
if ([self isFileExists:filePath])
{
return [[self fileAttributesWithFilePath:filePath] fileSize];
}
return 0.0;
}


2、文件大小转换成NSString

+ (NSString *)fileSizeStringConversionWithNumber:(double)fileSize
{
NSString *message = nil;

// 1MB = 1024KB 1KB = 1024B
double size = fileSize;
if (size > (1024 * 1024))
{
size = size / (1024 * 1024);
message = [NSString stringWithFormat:@"%.2fM", size];
}
else if (size > 1024)
{
size = size / 1024;
message = [NSString stringWithFormat:@"%.2fKB", size];
}
else if (size > 0.0)
{
message = [NSString stringWithFormat:@"%.2fB", size];
}

return message;
}


3、计算某个目录的大小

注意事项:统计过程中必须计算其所有层级子目录的相关文件大小,避免只统计当前子目录下的文件。

只统计到当前子目录时,是因为使用了不正确函数造成的,正确的统计方法如下所示。

// 错误的遍历方法
- (nullable NSArray<NSString *> *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error NS_AVAILABLE(10_5, 2_0)
// 正确的遍历方法
- (nullable NSArray<NSString *> *)subpathsAtPath:(NSString *)path;
// 正确的遍历方法
- (nullable NSDirectoryEnumerator<NSString *> *)enumeratorAtPath:(NSString *)path;


示例如下:

方法1

+ (double)fileSizeTotalNumberWithDirectory:(NSString *)directory
{
__block double size = 0.0;
if ([self isFileExists:directory])
{
NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:directory];
NSMutableArray *array = [[NSMutableArray alloc] init];
NSString *path = nil;
while (path = [dirEnum nextObject])
{
[array addObject:path];
}

[array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *filePath = [directory stringByAppendingPathComponent:obj];
if ([self isFileDirectoryWithFilePath:filePath])
{
[self fileSizeTotalNumberWithDirectory:filePath];
}
size += [self fileSizeNumberWithFilePath:filePath];
}];
}
return size;
}


方法2

+ (double)fileSizeTotalNumberWithDirectory:(NSString *)directory
{
__block double size = 0.0;
if ([self isFileExists:directory])
{
NSArray *array = [[NSFileManager defaultManager] subpathsAtPath:directory];

[array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *filePath = [directory stringByAppendingPathComponent:obj];
if ([self isFileDirectoryWithFilePath:filePath])
{
[self fileSizeTotalNumberWithDirectory:filePath];
}
size += [self fileSizeNumberWithFilePath:filePath];
}];
}
return size;
}


方法3

#include <sys/stat.h>
#include <dirent.h>

+ (double)fileSizeTotalNumberWithDirectory:(NSString *)directory
{
const char *folderPath = [directory cStringUsingEncoding:NSUTF8StringEncoding];
return [self folderSizeAtPath:folderPath];
}

// 遍历目录(注意添加头文件 #include <sys/stat.h> #include <dirent.h>)
+ (long long)folderSizeAtPath:(const char *)folderPath
{
long long folderSize = 0;
DIR *dir = opendir(folderPath);
if (dir == NULL)
{
return 0;
}
struct dirent *child;
while ((child = readdir(dir)) != NULL)
{
if (child->d_type == DT_DIR && (
(child->d_name[0] == '.' && child->d_name[1] == 0) || // 忽略目录 .
(child->d_name[0] == '.' && child->d_name[1] == '.' && child->d_name[2] == 0) // 忽略目录 ..
))
{
continue;
}

int folderPathLength = strlen(folderPath);
char childPath[1024]; // 子文件的路径地址
stpcpy(childPath, folderPath);
if (folderPath[folderPathLength-1] != '/')
{
childPath[folderPathLength] = '/';
folderPathLength++;
}
stpcpy(childPath+folderPathLength, child->d_name);
childPath[folderPathLength + child->d_namlen] = 0;
if (child->d_type == DT_DIR)
{
// directory
folderSize += [self folderSizeAtPath:childPath]; // 递归调用子目录
// 把目录本身所占的空间也加上
struct stat st;
if (lstat(childPath, &st) == 0)
{
folderSize += st.st_size;
}
}
else if (child->d_type == DT_REG || child->d_type == DT_LNK)
{
// file or link
struct stat st;
if (lstat(childPath, &st) == 0)
{
folderSize += st.st_size;
}
}
}
return folderSize;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: