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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to