Skip navigation.
 
mlRe: Obtain directory size.
FROM : Daniel Jalkut
DATE : Fri May 20 18:42:34 2005

On May 20, 2005, at 9:09 AM, Julian wrote:

> Hello,
> Since NSFileManager has no capabilities of returning the size of a 
> folder(a folder + contents), what would be a suitable & fast method 
> for obtaining this besides enumerating as it's slow as christmas. I 
> am looking for perhaps a carbon call to get this in one swoop.


I don't think there's anything that does it all for you.  I use 
Carbon to iterate, which is must faster than using NSEnumerator, but 
it still may not be the best way.

Note my comment about the resource forks.  The application I'm using 
this in doesn't grab the resource forks so it doesn't care about 
their size.

- (unsigned long long) fastFolderSizeAtFSRef:(FSRef*)theFileRef
{
    FSIterator    thisDirEnum = NULL;
    unsigned long long totalSize = 0;

    // Iterate the directory contents, recursing as necessary
    if (FSOpenIterator(theFileRef, kFSIterateFlat, &thisDirEnum) == 
noErr)
    {
        const ItemCount kMaxEntriesPerFetch = 256;
        ItemCount actualFetched;
        FSRef    fetchedRefs[kMaxEntriesPerFetch];
        FSCatalogInfo fetchedInfos[kMaxEntriesPerFetch];

        // DCJ Note right now this is only fetching data fork 
sizes... if we decide to include
        // resource forks we will have to add kFSCatInfoRsrcSizes

        OSErr fsErr = FSGetCatalogInfoBulk(thisDirEnum, 
kMaxEntriesPerFetch, &actualFetched,
                                        NULL, kFSCatInfoDataSizes | 
kFSCatInfoNodeFlags, fetchedInfos,
                                        fetchedRefs, NULL, NULL);
        while ((fsErr == noErr) || (fsErr == errFSNoMoreItems))
        {
            ItemCount thisIndex;
            for (thisIndex = 0; thisIndex < actualFetched; thisIndex++)
            {
                // Recurse if it's a folder
                if (fetchedInfos[thisIndex].nodeFlags & 
kFSNodeIsDirectoryMask)
                {
                    totalSize += [self 
fastFolderSizeAtFSRef:&fetchedRefs[thisIndex]];
                }
                else
                {
                    // add the size for this item
                    totalSize += fetchedInfos
[thisIndex].dataLogicalSize;
                }
            }

            if (fsErr == errFSNoMoreItems)
            {
                break;
            }
            else
            {
                // get more items
                fsErr = FSGetCatalogInfoBulk(thisDirEnum, 
kMaxEntriesPerFetch, &actualFetched,
                                        NULL, kFSCatInfoDataSizes | 
kFSCatInfoNodeFlags, fetchedInfos,
                                        fetchedRefs, NULL, NULL);
            }
        }
        FSCloseIterator(thisDirEnum);
    }
    return totalSize;
}

Related mailsAuthorDate
mlObtain directory size. Julian May 20, 18:09
mlRe: Obtain directory size. Brian Bergstrand May 20, 18:42
mlRe: Obtain directory size. Daniel Jalkut May 20, 18:42
mlRe: Obtain directory size. Jim Correia May 20, 18:50
mlRe: Obtain directory size. Chris Parker May 20, 19:00
mlRe: Obtain directory size. Jim Correia May 20, 19:00
mlRe: Obtain directory size. James Bucanek May 20, 19:20
mlRe: Obtain directory size. Julian May 20, 19:22
mlRe: Obtain directory size. Daniel Jalkut May 20, 19:57
mlRe: Obtain directory size. J.M.Brough May 20, 20:06
mlRe: Obtain directory size. Rosyna May 21, 01:26
mlRe: Obtain directory size. Steve Christensen May 21, 01:27