简体   繁体   中英

IOException: Unable To Delete Images Due To File Lock

I am Unable To Delete Image File From My Server Path It Gaves Error That The Process Cannot Access The File "FileName" Because it is being Used By Another Process. I Tried Many Methods But Still All In Vain. Please Help me Out in This Issue.

Here is My Code Snippet.

using System;
using System.Data;
using System.Web;
using System.Data.SqlClient;
using System.Web.UI;

using System.Web.UI.HtmlControls;
using System.Globalization;
using System.Web.Security;
using System.Text;
using System.DirectoryServices;
using System.Collections;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

//============ Main Block =================

       byte[] data = (byte[])ds.Tables[0].Rows[0][0];
        MemoryStream ms = new MemoryStream(data);
        Image returnImage = Image.FromStream(ms);

        returnImage.Save(Server.MapPath(".\\TmpImages\\SavedImage.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);


        returnImage.Dispose();       \\ I Tried this Dispose Method To Unlock The File But Nothing Done.

        ms.Close(); \\ I Tried The Memory Stream Close Method Also But Its Also Not Worked For Me.

       watermark();  \\ Here is My Water Mark Method That Print Water Mark Image on My Saved Image (Image That is Converted From Byte Array)


        DeleteImages();                   \\ Here is My Delete Method That I Call To Delete The Images



//===== ====  My Delete Method To Delete Files==================

            public void DeleteImages()

            {

                 try
                     {

                       File.Delete(Server.MapPath(".\\TmpImages\\WaterMark.jpg"));     \\This Image Deleted Fine.
                       File.Delete(Server.MapPath(".\\TmpImages\\SavedImage.jpg"));   \\ Exception Thrown On Deleting of This Image.
                     }

               catch (Exception ex)
                  {
                    LogManager.LogException(ex, "Error in Deleting Images.");
                    Master.ShowMessage(ex.Message, true);
                 }

             }



\\ ==== Method Declartion That Make Watermark of One Image On Another Image.=======

public void watermark()            
{


    //create a image object containing the photograph to watermark
    Image imgPhoto = Image.FromFile(Server.MapPath(".\\TmpImages\\SavedImage.jpg"));
    int phWidth = imgPhoto.Width;
    int phHeight = imgPhoto.Height;

    //create a Bitmap the Size of the original photograph
    Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);

    bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

    //load the Bitmap into a Graphics object
    Graphics grPhoto = Graphics.FromImage(bmPhoto);

    //create a image object containing the watermark
    Image imgWatermark = new Bitmap(Server.MapPath(".\\TmpImages\\PrintasWatermark.jpg"));
    int wmWidth = imgWatermark.Width;
    int wmHeight = imgWatermark.Height;

    //Set the rendering quality for this Graphics object
    grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

    //Draws the photo Image object at original size to the graphics object.
    grPhoto.DrawImage(
        imgPhoto,                               // Photo Image object
        new Rectangle(0, 0, phWidth, phHeight), // Rectangle structure
        0,                                      // x-coordinate of the portion of the source image to draw.
        0,                                      // y-coordinate of the portion of the source image to draw.
        phWidth,                                // Width of the portion of the source image to draw.
        phHeight,                               // Height of the portion of the source image to draw.
        GraphicsUnit.Pixel);                    // Units of measure

    //-------------------------------------------------------
    //to maximize the size of the Copyright message we will
    //test multiple Font sizes to determine the largest posible
    //font we can use for the width of the Photograph
    //define an array of point sizes you would like to consider as possiblities
    //-------------------------------------------------------


    //Define the text layout by setting the text alignment to centered
    StringFormat StrFormat = new StringFormat();
    StrFormat.Alignment = StringAlignment.Center;

    //define a Brush which is semi trasparent black (Alpha set to 153)
    SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));



    //define a Brush which is semi trasparent white (Alpha set to 153)
    SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));



    //------------------------------------------------------------
    //Step #2 - Insert Watermark image
    //------------------------------------------------------------

    //Create a Bitmap based on the previously modified photograph Bitmap
    Bitmap bmWatermark = new Bitmap(bmPhoto);
    bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
    //Load this Bitmap into a new Graphic Object
    Graphics grWatermark = Graphics.FromImage(bmWatermark);

    //To achieve a transulcent watermark we will apply (2) color
    //manipulations by defineing a ImageAttributes object and
    //seting (2) of its properties.
    ImageAttributes imageAttributes = new ImageAttributes();

    //The first step in manipulating the watermark image is to replace
    //the background color with one that is trasparent (Alpha=0, R=0, G=0, B=0)
    //to do this we will use a Colormap and use this to define a RemapTable
    ColorMap colorMap = new ColorMap();

    //My watermark was defined with a background of 100% Green this will
    //be the color we search for and replace with transparency
    colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
    colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);

    ColorMap[] remapTable = { colorMap };

    imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

    //The second color manipulation is used to change the opacity of the
    //watermark.  This is done by applying a 5x5 matrix that contains the
    //coordinates for the RGBA space.  By setting the 3rd row and 3rd column
    //to 0.3f we achive a level of opacity
    float[][] colorMatrixElements = {
                                            new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},       
                                            new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},        
                                            new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},        
                                            new float[] {0.0f,  0.0f,  0.0f,  0.3f, 0.0f},        
                                            new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}};
    ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);

    imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default,
        ColorAdjustType.Bitmap);

    //For this example we will place the watermark in the upper right
    //hand corner of the photograph. offset down 10 pixels and to the
    //left 10 pixles

    int xPosOfWm = ((phWidth - wmWidth) - 10);
    int yPosOfWm = 10;

    grWatermark.DrawImage(imgWatermark,
        new Rectangle(xPosOfWm, yPosOfWm, wmWidth, wmHeight),  //Set the detination Position
        0,                  // x-coordinate of the portion of the source image to draw.
        0,                  // y-coordinate of the portion of the source image to draw.
        wmWidth,            // Watermark Width
        wmHeight,            // Watermark Height
        GraphicsUnit.Pixel, // Unit of measurment
        imageAttributes);   //ImageAttributes Object

    //Replace the original photgraphs bitmap with the new Bitmap
    imgPhoto = bmWatermark;
    grPhoto.Dispose();
    grWatermark.Dispose();
    //save new image to file system.
    imgPhoto.Save(Server.MapPath(".\\TmpImages\\WaterMark.jpg"), ImageFormat.Jpeg);

    imgPhoto.Dispose();

   imgWatermark.Dispose();
}
imgPhoto = bmWatermark;

There's your problem, you didn't call imgPhoto.Dispose() first. The file is locked until the finalizer thread runs, that can take a while.

Use the using statement to avoid mistakes like this.

I had the same issue. So I used Process Monitor from SysInternals to see if a another process like my antivirus software was locking it. This was indeed the case for me, although a real-time backup service was also in contention for the file.

To get around this issue I used the following method to try and delete the file multiple times as the other process normally only holds a lock for a very short period of time.

public class FileHelper
{
    public static void Delete(string path)
    {
        int attempts = 0;
        const int maxAttempts = 3;

        do
        {
            try
            {
                attempts++;
                File.Delete(path);

                if (attempts > 1) Trace.TraceInformation("File delete succeeded");

                return;
            }
            catch (IOException)
            {
                Trace.TraceWarning("Could not access file for delete, attempt {0} of {1}", attempts, maxAttempts);

                if (attempts >= maxAttempts) throw;
            }
        }
        while (attempts < maxAttempts);
    }
}

Use Process Monitor by Mark Russinovich and Bryce Cogswell and find out which process has locked the file. Maybe it's your antivirus or something else.

Use "using" constructs. Should the code raise exception, the stream and Image won't be disposed, which can lead to locking the file.

using (MemoryStream ms = new MemoryStream( data ))
using (Image img = Image.FromStream(ms))
{
    //do sth with image
}

Plus if you reopen the image in watermark method, you should dispose it there as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM