IOException while calculating MD5 and SHA1 checksums

I have a problem while executing a method that computes MD5 and SHA1 checksums for a given file. My methods look like this:
SHA1:

    public string HashFile(string toHash)
    {
        SHA1 SHA1ENGINE = SHA1.Create();
        byte[] hashBytes = SHA1ENGINE.ComputeHash(File.Open(toHash, FileMode.Open, FileAccess.Read));

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hashBytes.Length; i++)
        {
            sb.Append(hashBytes[i].ToString("X2"));
        }
        return sb.ToString();
    }


MD5:

    public string HashFile(string toHash)
    {
        MD5 MD5ENGINE = MD5.Create();
        byte[] hashBytes = MD5ENGINE.ComputeHash(File.Open(toHash, FileMode.Open, FileAccess.Read));

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hashBytes.Length; i++)
        {
            sb.Append(hashBytes[i].ToString("X2"));
        }
        return sb.ToString();
    }


While executing one of these methods I get an IOException: The process cannot access the file '(PATHTOFILE)' because it is being used by another process.
This is a persistent problem, I cannot calculate checksums for any file on my PC. I'm logged as local admin and VS is opened as admin. This is persistent for any directory I've tried for example: C:\TEMP, C:\Users\Administrator\Desktop. I've also tried rebooting my PC, since there actually could be a process that locks files, but that didn't help.

At first I've tried to use:

byte[] hashBytes = SHA1ENGINE.ComputeHash(File.OpenRead(toHash));

But after encountering the described issue and some investigation I've changed that to:

byte[] hashBytes = SHA1ENGINE.ComputeHash(File.Open(toHash, FileMode.Open, FileAccess.Read));

This also didn't help.

Jon Skeet
people
quotationmark

You're opening the file without closing it. Just open the stream separately so you can close it in a using statement:

MD5 md5 = MD5.Create();
using (var stream = File.Open(...))
{
    var hash = md5.ComputeHash(stream);
    // ...
}

(I'd also suggest separating out the "convert to hex" code to avoid duplication. You could even have a method taking a filename and a HashAlgorithm to avoid duplication even further...)

That will avoid your code holding open file streams that will prevent code opening another file stream (including the same process)... but it won't help for any flie that is currently open elsewhere. If you can't open the file to read it, you simply won't be able to compute the hash.

people

See more on this question at Stackoverflow