Or Betzalel
Or Betzalel

Reputation: 2597

IOException File Is Used By Another Process

I've made a function that cycles and deletes two similar images in a given directory. (or even multiple directories) :

public void DeleteDoubles()
    {
        SHA512CryptoServiceProvider sha1 = new SHA512CryptoServiceProvider();
        string[] images = Directory.GetFiles(@"C:\" + "Gifs");
        string[] sha1codes = new string[images.Length];
        GifImages[] Gifs = new GifImages[images.Length];

        for (int i = 0; i < images.Length; i++)
        {
            sha1.ComputeHash(GifImages.ImageToByteArray(Image.FromFile(images[i])));
            sha1codes[i] = Convert.ToBase64String(sha1.Hash);
            Gifs[i] = new GifImages(images[i], sha1codes[i]);
        }

        ArrayList distinctsha1codes = new ArrayList();
        foreach (string sha1code in sha1codes)
            if (!distinctsha1codes.Contains(sha1code))
                distinctsha1codes.Add(sha1code);

        for (int i = 0; i < distinctsha1codes.Count; i++)
            if (distinctsha1codes.Contains(Gifs[i].Sha1Code))
            {
                for (int j = 0; j < distinctsha1codes.Count; j++)
                    if (distinctsha1codes[j] != null && distinctsha1codes[j].ToString() == Gifs[i].Sha1Code)
                    {
                        distinctsha1codes[j] = Gifs[i] = null;
                        break;
                    }
            }

        try
        {
            for (int i = 0; i < Gifs.Length; i++)
                if (Gifs[i] != null)
                    File.Delete(Gifs[i].Location);
        }
        catch (IOException)
        {
        }
    }

The problem is that after I'm left with the list of files I want to delete, I can't delete them because I get "System.IO.IOException file is being used by another process..."

I tried using procexp to see which processes are using my files and it seems the files are being used by MyApplication.vshost.exe. It starts using the file on that line :

sha1.ComputeHash(GifImages.ImageToByteArray(Image.FromFile(images[i])));

Meaning Image.FromFile(images[i]) opens the file but never closes it.

Upvotes: 1

Views: 1714

Answers (1)

Ed Swangren
Ed Swangren

Reputation: 124642

The documentation tells you as much:

The file remains locked until the Image is disposed.

So, you need to dispose of the image before attempting to delete it. Just keep it around for the shortest time possible like so:

for (int i = 0; i < images.Length; i++)
{
    using( var img = Image.FromFile( images[i] ) )
    {
        sha1.ComputeHash(imageToByteArray(img));
    }

    sha1codes[i] = Convert.ToBase64String(sha1.Hash);
    Gifs[i] = new GifImages(images[i], sha1codes[i]);
}

Upvotes: 3

Related Questions