Max94
Max94

Reputation: 125

Stream "File is open in another program"

i can't find some error in this code every check gave me this error " File is open in another program" i think there is some stream i haven't dispose

public static void CheckResolution(string imagePath)
{                
    var image = LoadSigleImageFromFile(imagePath);
    var baseArea = 2600 * 1000;//dimenzioni in risoluzione 
    FileStream stream = new FileStream(image.FileInfo.FullName, FileMode.Open, FileAccess.ReadWrite);
    try
    {
        Image img = Image.FromStream(stream);

        var imageArea = img.Height * img.Width;
        if (imageArea >= baseArea)
        {
            var scaleFactor = (imageArea / baseArea);
            var newVerticalRes = (int)(img.Height / scaleFactor);
            var newHorizontalRes = (int)(img.Width / scaleFactor);
            var newImage = ResizeImage(img, new Size(newHorizontalRes, newVerticalRes));

            if (File.Exists(imagePath))
                File.Delete(imagePath);
            newImage.Save(imagePath, ImageFormat.Jpeg);
        }
    }
    catch (Exception ex)
    {
        logger.Error("errore scala foto : " + ex.Message);
        //if (Boolean.Parse(ConfigurationManager.AppSettings["StopOnException"]))
        throw new Exception("CheckResolution errore scala foto : " + ex.Message);
    }
    finally
    {
        stream.Dispose();
    }
}

here the loadSingle... function

public static ImageFromFile LoadSigleImageFromFile(string file)
{
    var ris = new ImageFromFile();
    FileInfo fileInfo = new FileInfo(file);
    if (fileInfo.Name != "Thumbs.db")
        ris = (new ImageFromFile() { FileInfo = fileInfo });

    return ris;
}

Update ResizeImage function

 private static Image ResizeImage(Image imgToResize, Size size)
    {
        int sourceWidth = (int)imgToResize.Width;
        int sourceHeight = (int)imgToResize.Height;

        float nPercent = 0;
        float nPercentW = 0;
        float nPercentH = 0;

        nPercentW = ((float)size.Width / (float)sourceWidth);
        nPercentH = ((float)size.Height / (float)sourceHeight);

        if (nPercentH < nPercentW)
            nPercent = nPercentH;
        else
            nPercent = nPercentW;

        int destWidth = (int)(sourceWidth * nPercent);
        int destHeight = (int)(sourceHeight * nPercent);

        Bitmap b = new Bitmap(destWidth, destHeight);
        b.SetResolution(imgToResize.HorizontalResolution, imgToResize.VerticalResolution);
        Graphics g = Graphics.FromImage((System.Drawing.Image)b);
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
        g.Dispose();

        return (Image)b;
    }

Upvotes: 1

Views: 99

Answers (1)

Steve
Steve

Reputation: 216343

It is evident in your code that this block of lines

if (File.Exists(imagePath))
    File.Delete(imagePath);

tries to delete the same file opened by the Stream above. You should try to pospone the deletion of the file (and the following Save) only after the closing of the Stream opened before.

I could suggest these changes

public static void CheckResolution(string imagePath)
{      
    // Flag becomes true if the resize operation completes
    bool resizeCompleted = false;
    Image newImage = null;          

    // If file doesn't exist the code below returns null.
    var image = LoadSigleImageFromFile(imagePath);
    if(image == null) return;

    var baseArea = 2600 * 1000;//dimenzioni in risoluzione 
    using(FileStream stream = new FileStream(image.FileInfo.FullName, FileMode.Open, FileAccess.ReadWrite))
    {
        try
        {
            Image img = Image.FromStream(stream);
            var imageArea = img.Height * img.Width;
            if (imageArea >= baseArea)
            {
                ... resize ops ....
                // if (File.Exists(imagePath))
                      //File.Delete(imagePath);
                // newImage.Save(imagePath, ImageFormat.Jpeg);

                // Set the flag to true if resize completes
                resizeCompleted = true;
           }
        }
        catch (Exception ex)
        {
            logger.Error("errore scala foto : " + ex.Message);
            throw new Exception("CheckResolution errore scala foto : " + ex.Message);
        }
    }

    // Now you can delete and save....
    if(resizeCompleted)
    {
        // No need to check for existance. File.Delete doesn't throw if
        // the file doesn't exist
        File.Delete(imagePath);
        newImage.Save(imagePath, ImageFormat.Jpeg);
    }
}

public static ImageFromFile LoadSigleImageFromFile(string file)
{
    // Check if the file exists otherwise return null....
    var ris = null;
    if(File.Exists(file))
    {
        FileInfo fileInfo = new FileInfo(file);
        if (fileInfo.Name != "Thumbs.db")
           ris = (new ImageFromFile() { FileInfo = fileInfo });
    }
    return ris;
}

Moving the delete and save operations after the closing brace of the using block you are aure that the file is no more locked by your own program and you could proceed to the delete and save actions

Notice also that you should check for the existance of the input file before entering this code, otherwise an exception is here to wait for you.

Upvotes: 1

Related Questions