Does anyone know how to close a file? I saved an image... then when i try and save the image to the same filename.. or delete the file after i saved it... i get an error which states that the file is being used by another process. Has anyone come across a problem like this and if so how could I get around it?

I'm sure you checked, but did you make sure to close the resource for that file after you were finished with saving it? If not, that would certainly make it hard to do much of anything with it.

I am fairly new to C# lol so can you please write down in code by what you mean. I've been trying to chase down the source of this "generic error in GDI+" for over a week. I tried to delete the file after I saved it which is when i get the "file being used...". this is the code that I am using:

string OCRProcess(int StartX, int StartY, int EndX, int EndY)
        {
            
            string file = @"c:\Bitonal-Out.tif";            
            Bitmap CutImage = new Bitmap(EndX - StartX, EndY - StartY);       

            for (int x = StartX; x < EndX; x++)
            {
                for (int i = StartY; i < EndY; i++)
                    CutImage.SetPixel(x - StartX, i - StartY, bmpScreenshot.GetPixel(x, i));
            }

            Bitmap rgbBitmap = Converter.ConvertToRGB(CutImage);

            Bitmap bitonalBitmap = Converter.ConvertToBitonal(rgbBitmap);

            ImageCodecInfo imageCodecInfo = GetEncoderInfo("image/tiff");
            System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.Compression;
            EncoderParameters encoderParameters = new EncoderParameters(1);

            EncoderParameter encoderParameter = new EncoderParameter(encoder, (long)EncoderValue.CompressionCCITT4);
            encoderParameters.Param[0] = encoderParameter;
            
            bitonalBitmap.Save(file, imageCodecInfo, encoderParameters);

            MODI.Document doc = new MODI.Document();
            doc.Create(file);

            doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, false, false);

            MODI.Image img = (MODI.Image)doc.Images[0];

            doc.Close(false);
            encoderParameter.Dispose();
            CutImage.Dispose();
            bitonalBitmap.Dispose();

            return img.Layout.Text;
        }

The above function simply simply cuts an image from the screenshot, converts it to tiff, and does OCR on it. when i try to delete the file "bitonal-out.tif" i get the error message being use... Your help is greatly appreciated...

Dont work... heres the rest of the code that will allow you to run the program.

private static Bitmap bmpScreenshot;
        private static Graphics gfxScreenshot;

        public Form1()
        {
            InitializeComponent();
        }

private void convert_Click(object sender, EventArgs e)
        {
            string file = @"c:\Temp.tif";
            this.Hide();
            bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
            gfxScreenshot = Graphics.FromImage(bmpScreenshot);
            gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
            this.Show();

            label1.Text = OCRProcess(807, 74, 947, 92,file);
            label2.Text = OCRProcess(807, 92, 947, 110,file);
        }

        private static ImageCodecInfo GetEncoderInfo(String mimeType)
        {
            int j;
            ImageCodecInfo[] encoders;
            encoders = ImageCodecInfo.GetImageEncoders();
            for (j = 0; j < encoders.Length; ++j)
            {
                if (encoders[j].MimeType == mimeType)
                    return encoders[j];
            }
            return null;
        }

oo wait your going to have to modify it a little.. i was playing around with it so your going to have to add a string parameter to the OCRprocess and delete the string file already in place.

its the tif that i cant delete after I've saved it and used it for MODI. basically look at the bitonalImage.Save line

I just had the same problem and

I added
GC.Collect();
GC.WaitForPendingFinalizers();

after the doc.Close(true) and that fixed the problem.

I only found that by accident. I was in debug mode with a break point after doc.Close. I noticed if I waited for a while and resumed debugging the next iteration would work sometimes. So I decided to form GC to release whatever resources that was holding the lock and it worked.

I have the same problem with a simple text file.

I solved the problem by:

while (!File.Exists(fileName))
Thread.Sleep(100);

I tested this by changing the sleep time to 50 msec which still worked. Anything under that delay caused the exception.

I just had the same problem and

I added
GC.Collect();
GC.WaitForPendingFinalizers();

after the doc.Close(true) and that fixed the problem.

I only found that by accident. I was in debug mode with a break point after doc.Close. I noticed if I waited for a while and resumed debugging the next iteration would work sometimes. So I decided to form GC to release whatever resources that was holding the lock and it worked.

Thank you man!It helped me !!!!

another alternative is to read/write files through filestreams.
Filestreams dont create a file lock so they wont tie up your files, saving you the hastle of manually calling the grabage collector :)

Edited 6 Years Ago by Geekitygeek: n/a

Here is my final solution which seems to work quite well:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Toolbox
{
    public class FileCheck
    {
        public bool Exists(string fileName)
        {
            if (File.Exists(fileName))
            {
                Console.WriteLine("File Exists: " + fileName);
                return true;

            }
            return false;
        }

        public bool InUse(string fileName)
        {
            try
            {
                using (File.OpenRead(fileName))  // the using statement performs the close automatically!
                {
                    return false;
                }

            }
            catch (IOException)
            {
                Console.WriteLine("File is in use...");
            }
            return true;
        }
    }
}

There are 2 functions: FileCheck.Exists and FileCheck.InUse

.
.
.
            string filePath = "FileName and Path";
            int timeInSeconds = 10;   // depends on how long it takes

            Toolbox.FileCheck fCheck = new Toolbox.FileCheck();
            Toolbox.Timer timer = new Toolbox.Timer();

            bool fileInUse = true;
            bool elapsedTimer = false;

            // set the timer timeout value
            int timeOut = timeInSeconds;      // timeout in seconds
            timer.Start(timeOut);

            // check if file is in use
            while ((fileInUse = Check.InUse(filePath)))
            {
                if (timer.Elapsed())
                {
                    elapsedTimer = true;
                    Console.WriteLine("Timeout occurred waiting for file: <" + filePath + "> to be release!");
                    break;
                }
                else
                {
                    Console.WriteLine("File: <" + filePath + "> in Use...");
                }
                System.Threading.Thread.Sleep(100);
            }

            if (elapsedTimer)
            {
                Console.WriteLine("FileInUse: Timeout, File: <" + filePath + "> is still in use!");
                 // here you might return file in use flag:fileInUse true
            }
            else
            {
                Console.WriteLine("File: <" + filePath + "> has been released by the Operating System.");
                // here you might return file in use flag: fileInUse  false
            }

.
.
.

Here is the TimerRoutine:

using System;
using System.Collections.Generic;
using System.Text;

namespace Toolbox
{
    public class Timer
    {
        private long _endTime;  // getter/setter is called "timeOut"

        private long currentTime
        {
            get { return DateTime.Now.Ticks; }
        }
        private long timeOut
        {
            get { return _endTime; }
            set { _endTime = DateTime.Now.Ticks + new TimeSpan(0, 0, 0, (int)value).Ticks; }
        }
        public bool Start(int timeout)
        {
            timeOut = timeout;
            return true;
        }
        public bool Elapsed()
        {
            if (currentTime > timeOut)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

Edited 6 Years Ago by Nick Evan: Add code-tags

There is a small risk involved with that method; you have created a race condition. It is possible that the file is not in use when the check is made so it returns false, but the file is subsequently locked by another process.

What i've garnered from forum responses to questions like this is that the test isn't worth doing. To handle file locks you can
a) Test if file is locked before you use it
b) Try using it and handle the exception if its locked

The file system is volatile and can change between you doing the test and trying to access the record. Because the test could return a false positive you will still need to wrap your file access in try...catch blocks. If you are handling the exception anyway, then why spend time coding to perform the test?

Comments
good eye

Excuse me? I'm not saying your code doesnt work most of the time. The problem is that it wont work all of the time. There will be rare occasions where your test says the file exists right before it is deleted, or that it is not in use right before a process starts using it. The file system is volatile, its state is in no way fixed, hence, your test results in a race condition.

I'm not bothering you at all, i put forward an alternative view and you claimed it to be false. I simply asked you to be more specific to try and understand what part you didnt believe.

If the file is likely to be in use by your own process then you should re-evaluate how you access the file to prevent the lock. If you are concerned that another process will be using the file then you will/B] need exception handling. Regardless of the test you perform before your file access, it is still possible for the file to be locked and your code to throw an exception.

If you have problems like "The file is in use by another program or user" and you just don't get the whole proggraming stuff, one of the best tools for solving this would be Long Path Tool found at http://LongPathTool.com.

Long Path Tool can simplify and probably end your problems in unlocking, managing and renaming files that appear to have a long filename.

If you encounter errors as :


• Path too long

• Error cannot delete file: cannot read from source file or disk

• Cannot delete file: Access is denied

• There has been a sharing violation.

• Cannot delete file or folder The file name you specified is not valid or too long. Specify a different file name.

• The source or destination file may be in use.

• The file is in use by another program or user.

• Error Deleting File or Folder

• Make sure the disk is not full or write-protected and that the file is not currently in use.

• Error Copying File or Folder.

• Cannot remove folder.

• The filename or extension is too long.

• Path too deep.

• Destination Path Too Long.

• Could not find this item.

• Filename is not valid.

• The file could not be accessed.

• The path you entered, is too long. Enter a shorter path.

• File Name could not be found. Check the spelling of the filename, and verify that the file location is correct.

Your best solution is Long Path Tool . Go to http://LongPathTool.com and see the trial version to convince yourself.

This article has been dead for over six months. Start a new discussion instead.