4

I am really new to C#, so I've been working on a small pet project.

I've created a small program that compares the size of a directory with a given size. And if the directory is equal or larger, then it logs the path to that directory.

long size = Convert.ToInt32(Size) * 1024 * 1024;
string[] directories = Directory.GetDirectories(path, "*", SearchOption.AllDirectories); //the error occurs on this line
Array.Sort(directories);

foreach (string name in directories)
   try
   {
      DirectoryInfo directory = new DirectoryInfo(name);
      long dir = directory.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length);

   if (dir >= ScanSize)
      Console.WriteLine(directory);
   }

   catch (UnauthorizedAccessException) {  }

I should note that the input strings, and the long size = Convert.ToInt32(Size) come from the arguments in the Main()

I've read somewhere that I shouldn't use

Directory.GetDirectories(ScanPath, "*", SearchOption.AllDirectories);

since it'll get all the directories at once. But if I remove it, it only gets the directories in the given path, without any subdirectories. So I was told to apply recursion, but I found these fairly difficult. I read some things on file.Attributes, about hidden files, but I didn't know where to apply them.

I am the administrator of the system and I plan to run this on the entire data drive. D:\

But in this case the error occurs when the program tries to access the trash can of the D:\ But even if it skips this specific location, the error still comes back at another inaccessible one.

I'm hoping anyone here knows a good example or knows a website that explains this.

  • 1
    A few things to remember: 1) you wont be able to access certain OS directories which only allow the OS itself to access and not any other user account so this could be why. 2) if you are looking at network directories, your account may not have permissions to access them, this is also why. 3) if you are using this code in ASP.NET/MVC then it runs under the app pool account and could be that the directories don't have the user account added as allowed. you also don't specify in your code the initial path you are starting with – Ahmed ilyas Dec 12 '13 at 12:59
  • Take a look at this: http://stackoverflow.com/a/929418/425871 – Steve Dec 12 '13 at 13:10
  • @Ahmedilyas I've added some more information to the question. I hope this is a bit more clear. – user3095385 Dec 12 '13 at 13:22
  • Thanks. Well can you tell us what the folder in question throws the error when it is iterating through the directories? Again, as I said, there are some folders that even as an administrator, cannot get access to as they are OS folders/files or through another program where it exclusively is locked for another user account, regardless if you are an admin or not – Ahmed ilyas Dec 12 '13 at 13:25
  • @Ahmedilyas In this case, it's the trash can of the D:\ drive. I've heard about the OS only folders. The unauthorized exception did block them. But that's why I wrote that part about the `SearchOption.AllDirectories`. Because if I remove it, the code works. But if I delete it, it doesn't look any subdirectories. – user3095385 Dec 12 '13 at 13:31
  • Correct. The trash would be an exception here. you need to do a recursive loop perhaps or a single loop but having a try catch in the for each loop whilst you are going through the directories. – Ahmed ilyas Dec 12 '13 at 14:10

1 Answers1

0

Recursion is your friend here. Add error handling as needed in the loop. Try this:

    private static long maxSize = 5 * 1024 * 1024;

    static void Main(string[] args)
    {

        GetDirectorySize(new DirectoryInfo(@"d:\"));

    }

    static long GetDirectorySize(DirectoryInfo dir)
    {

        long size = 0;

        foreach(DirectoryInfo d in dir.EnumerateDirectories("*",SearchOption.TopDirectoryOnly)) {
            size += GetDirectorySize(d);
        }

        size += dir.EnumerateFiles("*",SearchOption.TopDirectoryOnly).Sum(fi => fi.Length);

        if (size > maxSize)
        {
            Console.WriteLine("Directory: {0} Size: {1}", dir, size);
        }

        return size;
    }
Jeremy Smith
  • 1,349
  • 8
  • 15
  • I'm not too fond with external data. Because all the data comes from arguments, in the main void. With prevents it from working. – user3095385 Dec 12 '13 at 14:31
  • This is just a cursory example of how you could recursively check the directory size. Use the method however you'd like. – Jeremy Smith Dec 12 '13 at 18:48
  • I've been testing your code and seems to work. More or less. Only problem now is that it doesn't write the paths. Do you have any suggestions on were place the line that does that? – user3095385 Dec 13 '13 at 10:30
  • Scratch that, I got it working just fine by adding .FullName behind dir. – user3095385 Dec 13 '13 at 12:37