1

I want to find all files in whole harddrive (.jpg, .png, .apk and a few other formats) but this code is not working..all it does is : for example if in my 'D:\' drive I have: 1)a image file 'i1', 2)a folder 'f1' which has image file and 3) another folder 'f2' which has image file and 'f2' contains folder 'f3' which has image file .It only performs 'calcFile()' on contents inside f1 and f2 but not on contents of f3 and i1 same happens with all other partitions .What is wrong here? Any help is appreciated. I hope you understand what is happening because that's the easiest way I could explain my situation, if more info is required just tell me. thanks :)

public void calcDirectory(string token)
    {
var validExtensions = new[]
        {

             ".jpg", ".png", ".apk"

        };
        foreach (string s in Directory.GetLogicalDrives())
        {
            DriveInfo driveInfo = new DriveInfo(s);
            if (driveInfo.IsReady)
            {


                foreach (string d in Directory.GetDirectories(s))
                {
                    FileAttributes attrs1 = File.GetAttributes(d);
                    if (!attrs1.HasFlag(FileAttributes.ReparsePoint))
                    {
                        if (!attrs1.HasFlag(FileAttributes.System))
                        { 
                    string[] allFilesInDir = Directory.GetFiles(d);
                    for (int i = 0; i < allFilesInDir.Length; i++)
                    {
                        string file = allFilesInDir[i];
                        string extension = Path.GetExtension(file);
                        if (validExtensions.Contains(extension))
                        {
                            string p = Path.GetFullPath(file);
                            FileAttributes attrs = File.GetAttributes(p);
                            if (attrs.HasFlag(FileAttributes.ReadOnly))
                            {
                                File.SetAttributes(p, attrs & ~FileAttributes.ReadOnly);
                                calcFile(file, token);
                            }
                            else
                            {
                                calcFile(file, token);
                            }
                        }
                    }

                }
            }
           }
         }
        }
    }

and I call the calcDirectory() here

public void start()
    {
         string token = File.ReadAllText(tokencalcalculated);
         calcDirectory(token); 
    }
panman
  • 75
  • 15
  • possible duplicate of http://stackoverflow.com/questions/9830069/searching-for-file-in-directories-recursively , likely you have to specify a SearchOption Directory.GetFiles(d,SearchOption.AllDirectories) – Ahmad Dec 09 '15 at 17:45
  • that is not possible because the overload for GetFiles does not permit that...I already tried that – panman Dec 09 '15 at 17:47
  • Have a look at https://msdn.microsoft.com/en-us/library/ms143316(v=vs.110).aspx – Ahmad Dec 09 '15 at 17:48
  • You could also use recursion, check out this. http://stackoverflow.com/questions/929276/how-to-recursively-list-all-the-files-in-a-directory-in-c?answertab=active#tab-top – thinklarge Dec 09 '15 at 17:52
  • 1
    yes but if I add Directory.GetFiles(d,SearchOption.AllDirectories) it is not possible because overload of GetFiles must contain(path,searchpattern,SearchOption) I am unable to only specify path and searchoption..thats according to me ..am I missing something? – panman Dec 09 '15 at 17:53
  • can any one just modify my code for the purpose..? I would be really thankful because I am new at this and dont understand it well... thanks – panman Dec 09 '15 at 17:58
  • @panam if I'd seen this comment before I started working on it I wouldn't have put in the effort. It makes it seem like you want this to be spoon fed to you and not to learn. That said, I hope my answer helps you as it shows you how you can use recursion to answer this question. – thinklarge Dec 09 '15 at 18:13
  • I apologize if you felt that way , I too want to learn but dont know where to start so I asked for modification . I know you pointed towards the resource to help me but it was hard to understand thats why I asked for help...anyway thanks for helping – panman Dec 09 '15 at 18:20

2 Answers2

1

You are only enumerating the root directories but no subdirectories. Instead of Directory.GetDirectories(s) use

foreach(string d in Directory.GetDirectories(s, "*", SearchOption.AllDirectories))

But be aware of infinite loops due to links in your subdirectories (see MSDN on SearchOption.AllDirectories).

And you should be aware of user access rights. You should put a try...catch around your GetFiles part in case you don't have access rights for a specific directory (See this question).

Community
  • 1
  • 1
René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • as you predicted it is giving error saying access to C\document and setting is denied which is a ReparsePoint i guess so how can I ignore such files I even included try..catch and I also want to exclude files like Recycler and System Volume Information – panman Dec 09 '15 at 18:09
  • Please see the linked question. Yours is a duplicate of that now. – René Vogt Dec 09 '15 at 18:12
1

I created a function based on your code that will recursively search the directory for anything matching your pattern. You'll have to call this from your loop of the base directories.

public static void crawlDirectory(string token,string directory)
    {
        if (string.IsNullOrEmpty(directory)) return;
        var validExtensions = new[]
        {

             ".jpg", ".png", ".apk"

        };

        foreach (string d in Directory.GetDirectories(directory))
        {
            FileAttributes attrs1 = File.GetAttributes(d);
            if (!attrs1.HasFlag(FileAttributes.ReparsePoint) && !attrs1.HasFlag(FileAttributes.System))
            {
                string[] allFilesInDir = Directory.GetFiles(d);
                for (int i = 0; i < allFilesInDir.Length; i++)
                {
                    string file = allFilesInDir[i];
                    string extension = Path.GetExtension(file);
                    if (validExtensions.Contains(extension))
                    {
                        string p = Path.GetFullPath(file);
                        FileAttributes attrs = File.GetAttributes(p);
                        if (attrs.HasFlag(FileAttributes.ReadOnly))
                        {
                            File.SetAttributes(p, attrs & ~FileAttributes.ReadOnly);
                            calcFile(file, token);
                        }
                        else
                        {
                            calcFile(file, token);
                        }
                    }
                }
            }

            crawlDirectory(d, token);
        }
    }
thinklarge
  • 672
  • 8
  • 24
  • thanks for replying but it shows error on calcDirectory(d); it says "An object reference is required for the non-static field, method, or property " – panman Dec 09 '15 at 18:16
  • try converting it from static to "not" static. See if that works. Also you have to insert this in place of the current loop over directories. – thinklarge Dec 09 '15 at 18:27
  • 1
    after studying your code, I found that the last call to calcDirectory(d) would not be appropriate because 'd' would be path and my calcDirectory() accepts 'token'(password) as parameter – panman Dec 09 '15 at 18:46
  • OH MAN, you are 100% correct. That was an error on my part. That is where the recursion is meant to happen. I did a quick refactor before I posted and messed up. That call should be to crawlDirectory(d, token). I made the appropriate change above. – thinklarge Dec 09 '15 at 18:47
  • it solves part of my problem it , if you look at my question at start i mentioned that it doesnt reach till 'i1'(the file that is directly inside D:\\ eg:D:\\image.jpg) and it still does not .. but thanks for your help it solved majority of my problem.. – panman Dec 09 '15 at 19:30