none
How to prevent stream reader to read locked files RRS feed

  • Question

  • Hi,

    I am writing a application that hashes files to find duplicates. First it scannes for all files in a drive or folder and then passes all the files it found to the code below, file by file. But when de the file is in use or the program does not have access rights it quits with an exception. Is there a way to make sure the program doesnt try to read the file when it is in use or missing the rights to read it?

    Regards, 

    public string HashIt(string file)
            {
                try
                {
                    using (var md5 = MD5.Create())
                    {
                        using (var stream = File.OpenRead(file))
                        {
                            return (Encoding.Default.GetString(md5.ComputeHash(stream)));
                        }
                    }
                }
                catch (Exception)
                {
                    throw;
                }            
            }

    Sunday, December 17, 2017 8:56 PM

All replies

  • Hello AnotherRob,

    You could get the file permissions and then you could determine whether has enough right to access it. The following is a simple example for refer.

    public static bool HasReadPermission(string path)
            {    
                var writeAllow = false;
                var writeDeny = false;
    
                var accessRules = File.GetAccessControl(path, AccessControlSections.Access).GetAccessRules(true, true, typeof(SecurityIdentifier));
                SecurityIdentifier users = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
    
                foreach (FileSystemAccessRule rule in accessRules)
                {
                    if (rule.IdentityReference == users)
                    {
                        if ((FileSystemRights.Read & rule.FileSystemRights) != FileSystemRights.Read)
                            continue;
                        if (rule.AccessControlType == AccessControlType.Allow)
                            writeAllow = true;
                        else if (rule.AccessControlType == AccessControlType.Deny)
                            writeDeny = true;
                    }       
                }
                return writeAllow && !writeDeny;
            }

    How to use

    using (var md5 = MD5.Create())
                    {
                        if (HasReadPermission(file))
                        {
                            using (var stream = File.OpenRead(file))
                            {
                                return (Encoding.Default.GetString(md5.ComputeHash(stream)));
                            }
                        }
                        else {
                            return "the file doesn't have enough permissions";
                        }
                    }

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, December 18, 2017 3:19 AM
    Moderator
  • Have you considered to analyse the caught exception and skip the files in some cases (e.g. UnauthorisedAccessException)?

    Monday, December 18, 2017 7:11 AM
  • Hi,

    Thanks for the quick response, I will try this code but I cant get the MD5 to work and I am reinstalling/reparing c# at this moment. Once the MD5 is working ill try the code from your answer.

    Regards,

    Rob.

    Monday, December 18, 2017 12:05 PM
  • "But when de the file is in use or the program does not have access rights it quits with an exception."

    You cannot prevent this. It is one of the costs of working with external resources. The only thing you can do is use your try-catch block to catch the "recoverable" errors and either try again or ignore them. Note that you shouldn't catch all exceptions, just the ones you want to ignore. So in the code you posted, replace Exception with the correct exception type. Note you can have multiple catch blocks (one for each unique exception type).


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, December 18, 2017 2:41 PM
    Moderator