views:

661

answers:

3

Right now all I am using to calculate the size are the files in the folders. I do not think this is all of it, because the content database size is about 15gb. When I calculate the size of all the files I get around 10gb. Does anyone know what I may be missing?

Here is the code I have so far.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Globalization;

namespace WebSizeTesting
{
class Program
{


    static void Main(string[] args)
    {
        long SiteCollectionBytes = 0;

        using (SPSite mainSite = new SPSite("http://sharepoint-test"))
        {
            // loop through the websites
            foreach (SPWeb web in mainSite.AllWebs)
            {

                long webBytes = GetSPFolderSize(web.RootFolder);

                // Add in size of each web site's recycle bin

                webBytes += web.RecycleBin.OfType<SPRecycleBinItem>().Select(item => item.Size).ToArray<long>().Sum();

                Console.WriteLine("Url: {0}, Size: {1}", web.Url, ConvertBytesToDisplayText( webBytes ));

                SiteCollectionBytes += webBytes;
            }


            long siteCollectionRecycleBinBytes = mainSite.RecycleBin.OfType<SPRecycleBinItem>().Select(item => item.Size).ToArray<long>().Sum();

            Console.WriteLine("Site Collection Recycle Bin: " + ConvertBytesToDisplayText(siteCollectionRecycleBinBytes));

            SiteCollectionBytes += siteCollectionRecycleBinBytes;
        }

        Console.WriteLine("Total Size: " + ConvertBytesToDisplayText(SiteCollectionBytes));

        Console.ReadKey();
    }



    public static long GetSPFolderSize(SPFolder folder)
    {
        long byteCount = 0;

        // calculate the files in the immediate folder
        foreach (SPFile file in folder.Files)
        {
            byteCount += file.TotalLength;

            // also include file versions
            foreach (SPFileVersion fileVersion in file.Versions)
            {
                byteCount += fileVersion.Size;
            }

        }

        // Handle sub folders
        foreach (SPFolder subFolder in folder.SubFolders)
        {
            byteCount += GetSPFolderSize(subFolder);
        }

        return byteCount;
    }

    public static string ConvertBytesToDisplayText(long byteCount)
    {
        string result = "";

        if (byteCount > Math.Pow(1024, 3))
        {
            // display as gb
            result = (byteCount / Math.Pow(1024, 3)).ToString("#,#.##", CultureInfo.InvariantCulture) + " GB";
        }
        else if (byteCount > Math.Pow(1024, 2))
        {
            // display as mb
            result = (byteCount / Math.Pow(1024, 2)).ToString("#,#.##", CultureInfo.InvariantCulture) + " MB";
        }
        else if (byteCount > 1024)
        {
            // display as kb
            result = (byteCount / 1024).ToString("#,#.##", CultureInfo.InvariantCulture) + " KB";
        }
        else
        {
            // display as bytes
            result = byteCount.ToString("#,#.##", CultureInfo.InvariantCulture) + " Bytes";
        }

        return result;
    }
}
}

edit 2:15 pm 3/1/2010 cst I added in the ability to count file versions as part of the size to the code. As was suggested by Goyuix in the post below. It still is off by a considerable amount of the physical database size.

edit 8:38 am 3/3/2010 cst I added in the calculating of the recycle bin size for each web, and the site collection recycle bin. These changes where suggested by ArjanP. Also i wanted to add, that I am very open to more efficient ways of doing this.

+1  A: 

The content database also stores configuration information, like what lists actually exist, features, permissions, etc... while that would probably not account for 5GB of data, it is something to consider. Also, each file is also typically associate with an SPListItem that may contain metadata for that file.

Do you have versioning turned on for any of the lists / libraries? If so, you will also need to check the SPListItem.Versions property for each version.

Goyuix
It looks like file versions are part of the answer. I added in a loop of the file versions of each file. That added a little more than 1.5 gb, which is a pretty large percentage of the total I would think. Our users do use sharepoint versions quite a bit. I have edited the code in the post to reflect this.
Anonymous Coward
A: 

I'm not quite sure your code considers list attachments, too.

naivists
In my initial testing, it looks like attached items to list are part of the count. I tested this by creating a new custom list. I then made a new blank item, created a 16mb rtf file. I then added that file to the blank item as an attachment. 16mb of storage was added to the total count when I ran the code on a test server.
Anonymous Coward
+1  A: 

Did you consider the Trash Can? There will be cans for Webs and the Site Collection, all taking up space in the content database.

There will always be 'overhead' in a content database.. every 'empty' Web will consume a number of bytes already. 30% seems much but not excessive, it depends on the ratio of content and the number of webs.

ArjanP
I have figured out what I think is the code necessary to add in the recycle bin files. Those added about 500mb to the total. Which brings my total up to 12.2gb out of 15gb, so that is still 3gb of overhead. Part of this whole process is pin pointing exactly where each part of the sharepoint install grows the most. How would I calculate the overhead you mentioned for each web?
Anonymous Coward
Create a new subsite while no-one is using the server and see how much your database grows..
ArjanP
Also, there are 2 recycle bins.. 1 for each subsite, like /subsite/_layouts/recyclebin.aspx and 1 for the site collection, see /_layouts/AdminRecycleBin.aspx
ArjanP
I've gotten both of those. I calculated the web(sub site) one with: webBytes += web.RecycleBin.OfType<SPRecycleBinItem>().Select(item => item.Size).ToArray<long>().Sum();Then I used this to calculate the site collection one:long siteCollectionRecycleBinBytes = mainSite.RecycleBin.OfType<SPRecycleBinItem>().Select(item => item.Size).ToArray<long>().Sum();
Anonymous Coward