Re: Calculating file size
Re: Calculating file size
- Subject: Re: Calculating file size
- From: email@hidden
- Date: Tue, 29 Apr 2008 06:49:28 -0400
I dug up some code that might help. This uses a category to replace
NSFileManager's fileAttributesAtPath: traverseLink and provides more
attributes than the standard implementation. With this category
method, you can continue to use the directory enumerator, so your
calculation becomes:
NSNumber *dataSize = [attributes objectForKey:NSFileDataSize];
NSNumber *rsrcSize = [attributes objectForKey:NSFileRsrcSize];
totalSize += [dataSize longLongValue] + [rsrcSize longLongValue];
Not the most efficient, but one approach. I am curious to hear
comments on the code, too. It worked for my needs, but I may have
overlooked some things.
Aaron
---- NSFileManagerAddtions:
//
// NSFileManagerAdditions.h
//
extern NSString const *NSFileAccessDate;
extern NSString const *NSFileBackupDate;
extern NSString const *NSFileAttributeModificationDate;
extern NSString const *NSFileDataSize;
extern NSString const *NSFileRsrcSize;
extern NSString *NSFileTypePipe;
---- NSFileManagerAdditions.m:
#import "NSFileManagerAdditions.h"
#include <sys/stat.h>
#include <sys/param.h>
@implementation NSFileManager (NSFileManagerAdditions)
- (NSDictionary *)fileAttributesAtPath:(NSString *)fullPath
traverseLink:(BOOL)flag
{
OSErr err;
OSStatus status;
FSRef ref;
Boolean isDirectory;
FSCatalogInfo info;
const char *fullPathRepresentation = [fullPath
fileSystemRepresentation];
int statResult;
struct stat statBuf;
if (flag)
statResult = stat( fullPathRepresentation, &statBuf);
else
statResult = lstat( fullPathRepresentation, &statBuf);
if (statResult) return nil;
status = FSPathMakeRef( (const unsigned char*)fullPathRepresentation,
&ref, &isDirectory);
FSPermissionInfo *permissions = (FSPermissionInfo *) &info.permissions;
err = FSGetCatalogInfo( &ref, kFSCatInfoGettableInfo, &info, NULL,
NULL, NULL);
if (err) {
if ( !(err == nsvErr || err == fnfErr) )
NSLog(@"Error getting file attributes: %hd path: %@", err,
fullPath);
return nil;
}
// File type
NSString *fileType = NSFileTypeUnknown;
UInt16 type = statBuf.st_mode & S_IFMT;
if (type == S_IFREG) fileType = NSFileTypeRegular;
else if (type == S_IFDIR) fileType = NSFileTypeDirectory;
else if (type == S_IFLNK) fileType = NSFileTypeSymbolicLink;
else if (type == S_IFIFO) fileType = NSFileTypePipe;
else if (type == S_IFCHR) fileType = NSFileTypeCharacterSpecial;
else if (type == S_IFBLK) fileType = NSFileTypeBlockSpecial;
else if (type == S_IFSOCK)fileType = NSFileTypeSocket;
// Dates
NSTimeInterval creationDateInterval =
(double)info.createDate.lowSeconds;
if (info.createDate.highSeconds) creationDateInterval +=
info.createDate.highSeconds * 4294967296.0;
if (info.createDate.fraction) creationDateInterval +=
info.createDate.fraction / 65536.0;
NSTimeInterval modDateInterval =
(double)info.contentModDate.lowSeconds;
if (info.contentModDate.highSeconds) modDateInterval +=
info.contentModDate.highSeconds * 4294967296.0;
if (info.contentModDate.fraction) modDateInterval +=
info.contentModDate.fraction / 65536.0;
NSTimeInterval accessDateInterval = (double)info.accessDate.lowSeconds;
if (info.accessDate.highSeconds) accessDateInterval +=
info.accessDate.highSeconds * 4294967296.0;
if (info.accessDate.fraction) accessDateInterval +=
info.accessDate.fraction / 65536.0;
NSTimeInterval backupDateInterval = (double)info.backupDate.lowSeconds;
if (info.backupDate.highSeconds) backupDateInterval +=
info.backupDate.highSeconds * 4294967296.0;
if (info.backupDate.fraction) backupDateInterval +=
info.backupDate.fraction / 65536.0;
NSTimeInterval attributeModDateInterval =
(double)info.attributeModDate.lowSeconds;
if (info.attributeModDate.highSeconds) attributeModDateInterval +=
info.attributeModDate.highSeconds * 4294967296.0;
if (info.attributeModDate.fraction) attributeModDateInterval +=
info.attributeModDate.fraction / 65536.0;
// Sizes
NSNumber *dataSize = [NSNumber
numberWithUnsignedLongLong:info.dataLogicalSize];
NSNumber *rsrcSize = [NSNumber
numberWithUnsignedLongLong:info.rsrcLogicalSize];
// HFS Type & Creator
NSNumber *fileHFSType, *fileCreator;
if (isDirectory) {
FileInfo *fileInfo = (FileInfo *) &info.finderInfo;
fileHFSType = [NSNumber numberWithUnsignedLong:fileInfo->fileType];
fileCreator = [NSNumber numberWithUnsignedLong:fileInfo->fileCreator];
}
else {
fileHFSType = [NSNumber numberWithUnsignedLong:0];
fileCreator = [NSNumber numberWithUnsignedLong:0];
}
return [NSDictionary dictionaryWithObjectsAndKeys:
fileType, NSFileType,
[NSNumber numberWithUnsignedInt:info.nodeID], NSFileSystemFileNumber,
[NSNumber numberWithInt:statBuf.st_nlink], NSFileReferenceCount,
[NSNumber numberWithInt:statBuf.st_dev], NSFileSystemNumber,
[NSDate dateWithTimeIntervalSince1904:modDateInterval],
NSFileModificationDate,
[NSDate dateWithTimeIntervalSince1904:creationDateInterval],
NSFileCreationDate,
[NSDate dateWithTimeIntervalSince1904:accessDateInterval],
NSFileAccessDate,
[NSDate dateWithTimeIntervalSince1904:backupDateInterval],
NSFileBackupDate,
[NSDate dateWithTimeIntervalSince1904:attributeModDateInterval],
NSFileAttributeModificationDate,
[NSNumber numberWithUnsignedInt:permissions->userID],
NSFileOwnerAccountID,
[NSNumber numberWithUnsignedInt:permissions->groupID],
NSFileGroupOwnerAccountID,
[NSNumber numberWithUnsignedInt:(permissions->mode & 0xFFF)],
NSFilePosixPermissions,
dataSize, NSFileSize,
dataSize, NSFileDataSize,
rsrcSize, NSFileRsrcSize,
fileHFSType, NSFileHFSTypeCode,
fileCreator, NSFileHFSCreatorCode,
nil];
// Missing:
// NSFileExtensionHidden
// NSFileGroupOwnerAccountName
// NSFileOwnerAccountName
}
NSString const *NSFileAccessDate = @"NSFileAccessDate";
NSString const *NSFileBackupDate = @"NSFileBackupDate";
NSString const *NSFileAttributeModificationDate =
@"NSFileAttributeModificationDate";
NSString const *NSFileDataSize = @"NSFileDataSize";
NSString const *NSFileRsrcSize = @"NSFileRsrcSize";
NSString *NSFileTypePipe = @"NSFileTypePipe";
---- end NSFileManagerAdditions.m
On Apr 26, 2008, at 9:50 PM, Cocoa Dev wrote:
Hello,
I was wondering what was the best way to calucate folder size with
cocoa? I
was able to do this but it does not include resource forks:
#import <Foundation/Foundation.h>
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *path = [@"/Folder" stringByExpandingTildeInPath];
NSDirectoryEnumerator *e = [[NSFileManager defaultManager]
enumeratorAtPath
:path];
NSString *file;
unsigned long long totalSize = 0;
while ((file = [e nextObject])) {
NSDictionary *attributes = [e fileAttributes];
NSNumber *fileSize = [attributes objectForKey:NSFileSize];
totalSize += [fileSize longLongValue];
}
printf("Total size: %lld\n", totalSize);
[pool release];
}
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden