I’m trying to write some code that deletes an image off the hard-disk once the user clicks on some delete button. Sometimes I get the following exception and sometimes I do not. And when I actually do, if I try to delete it again, it does work most of the time.
This is the exception:
System.IO.IOException: The process cannot access the file because it
is being used by another process.
I guess I should provide some details on what is happening exactly:
- User uploads an image, which is then displayed on the screen so the user can see what he/she has just uploaded.
- A delete button is shown to the user in case he/she decides that they do not really want to upload this image.
- When the user clicks the delete button, I call a method that deletes the image and all of its previously created thumbs.
- Finally, the image is remove from the screen and the user can upload other images.
I’m not sure how I could solve this problem because the exception does not provide any information about which other process is holding onto the file. Any ideas?
UPDATE:
public byte[] ResizeImageToBytes(string path, int size, string name)
{
var newImage = Image.FromFile(path);
int newWidth; int newHeight;
if (size == 470)
{
if (newImage.Height != 250)
{
newWidth = (int)Math.Round(newImage.Width * (100 / (newImage.Height / 250)) * 0.01);
newHeight = 250;
}
else
{
newWidth = newImage.Width;
newHeight = newImage.Height;
}
}
else
{
if (newImage.Width > newImage.Height)
{
newWidth = size;
newHeight = newImage.Height*size/newImage.Width;
}
else
{
newWidth = newImage.Width*size/newImage.Height;
newHeight = size;
}
}
var thumb = new Bitmap(newWidth, newHeight);
var gfx = Graphics.FromImage(thumb);
gfx.CompositingQuality = CompositingQuality.HighQuality;
gfx.SmoothingMode = SmoothingMode.HighQuality;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
var rect = new Rectangle(0, 0, newWidth, newHeight);
gfx.DrawImage(newImage, rect);
var ms = new MemoryStream();
thumb.Save(ms, newImage.RawFormat);
return ms.GetBuffer();
}
public void SaveImage(byte[] toSave, string path)
{
using (var ms = new MemoryStream())
{
ms.Write(toSave, 0, toSave.Length);
using(var theImage = Image.FromStream(ms))
{
theImage.Save(path);
}
}
}
[HttpPost]
public ActionResult Upload()
{
var newFile = System.Web.HttpContext.Current.Request.Files["Filedata"];
string guid = Guid.NewGuid() + newFile.FileName;
string itemImagesFolder = Server.MapPath(Url.Content("~/Content/ItemImages/"));
string fileName = itemImagesFolder + "originals/" + guid;
newFile.SaveAs(fileName);
string finalPath;
foreach (var dim in ImageDimensionsList.Options)
{
var bytes = _imageService.ResizeImageToBytes(fileName, dim.Width, guid);
finalPath = itemImagesFolder + dim.Title + "/" + guid;
_imageService.SaveImage(bytes, finalPath);
}
return Content(guid);
}
You aren’t disposing any of the disposable resources you are working with in your
ResizeImageToBytesmethod. This leaves leaking handles in your application and of course locked files. Try this:As far as your
SaveImagemethod is concerned, well, this method seems redundant to me as it already exists in the .NET framework. It’s called File.WriteAllBytes: