-1

I've tried so many different ways to do this, and it's still telling me the file is in use when I try to delete it before saving it again.

if (Clipboard.GetDataObject().GetData(DataFormats.Bitmap) != null)
{
    if (File.Exists(filename)) { File.Delete(filename); }
    using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite))
    {
        ImageConverter converter = new ImageConverter();
        byte[] bytes = (byte[])converter.ConvertTo(Clipboard.GetDataObject().GetData(DataFormats.Bitmap), typeof(byte[]));
        fs.Write(bytes, 0, bytes.Length);
        fs.Close();
        fs.Dispose();
    }
}

As you can see, I have everything in a "using" block. I also "close" the file, and even tried explicitly calling the "dispose" as well. But when I run the code again, it STILL tells me the file is in use. What can I do to be able to overwrite the file?

I've also tried it this way:

using (Bitmap bmp = new Bitmap((Bitmap)Clipboard.GetDataObject().GetData(DataFormats.Bitmap)))
{
    if (bmp != null)
    {
        if (File.Exists(filename)) { File.Delete(filename); }
        using (MemoryStream memory = new MemoryStream())
        {
            using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite))
            {
                bmp.Save(memory, ImageFormat.Bmp);
                byte[] bytes = memory.ToArray();
                fs.Write(bytes, 0, bytes.Length);
                fs.Close();
            }
            memory.Dispose();
        }
        bmp.Dispose();
        break;
    }
}

and it still gives me the same error.

Igor
  • 60,821
  • 10
  • 100
  • 175
Starfleet Security
  • 1,813
  • 3
  • 25
  • 31
  • Did you add this later on, after you tried to close your program without deleting the stream? It is possible the old stream "floats around" your computer and blocks the file and now you are not able to close it because you don't have access to it. You could try restarting your computer, then this issue should be solved (if this is the problem). – Lehue Dec 13 '16 at 15:06
  • There might be other ways to kill a lost filestream, but I don't know of any (honestly I've never looked for them either). – Lehue Dec 13 '16 at 15:07
  • There is a probably a reason for it. Is there anything else that makes use of the file/filepath you created? Maybe the file path is returned to something that does something with it and locks it or does not clean up a stream? Most likely its not in the code you have shown us so far as there is a using block around your FileStream. I am willing to bet if you put this in a loop it would also succeed (assuming the file is not locked when you enter). – Igor Dec 13 '16 at 15:08
  • Is it possible that the storage medium is slow and the data hasn't been written through yet? Like, when you can't safely eject your USB stick because data is still being written? Is the image big? – Peter - Reinstate Monica Dec 13 '16 at 15:10
  • I don't think it's any of these things so far. If I stop execution and start it again, it works fine. It's only while the program is running that the second save won't work. – Starfleet Security Dec 13 '16 at 15:11
  • Then the process keeps a lock on it somewhere else in your code or there is a race condition where this code is entered simultaneously by 2 or more threads all using the same filename. This would be easy to do if the save takes a very long time and another event triggers the same code block. – Igor Dec 13 '16 at 15:12
  • The save doesn't take long, it's a very small file, and there's nothing else happening anywhere that does anything with this file. – Starfleet Security Dec 13 '16 at 15:13
  • Please post the complete Exception including the type, message, stack trace, and the same for each inner exception recursively. – Igor Dec 13 '16 at 15:15
  • 1
    Nothing much to it, it just says "The process cannot access the file '*path_to_file*' because it is being used by another process." – Starfleet Security Dec 13 '16 at 15:19
  • 2
    Possible duplicate of [IOException: The process cannot access the file 'file path' because it is being used by another process](http://stackoverflow.com/questions/26741191/ioexception-the-process-cannot-access-the-file-file-path-because-it-is-being) – Igor Dec 13 '16 at 15:21
  • Have you tried adding `fs.Flush();` to flush the file write buffer as well? – Kateract Dec 13 '16 at 15:26
  • Igor - I've done everything in that post and it still doesn't work. Kateract - Tried the "flush", still get same error. – Starfleet Security Dec 13 '16 at 15:30
  • Check permissions that you can alter (ie. delete) existing content on the file directory for the user context that your process is running under. – Igor Dec 13 '16 at 15:38
  • Also wrap everything inside of `if (bmp != null)` in your 2nd example in a `for(int i = 0; i < 5; i++)` loop, if you can do that then its proof that outside your code (ie. what you have not posted) something else is making use of the file you create and that is why you cant lock it again when you re-enter the same block. – Igor Dec 13 '16 at 15:39
  • Actually, @Igor I think this may be an exact duplicate of [this question](http://stackoverflow.com/questions/13335349/the-process-cannot-access-the-file-because-it-is-being-used-by-another-process?rq=1), as OP is using `File.Create` and may just need to use `WriteAllBytes` for this purpose. – gravity Dec 13 '16 at 15:39
  • @gravity - there is no code above with `File.Create`.... – Igor Dec 13 '16 at 15:42
  • @gravity - totally different. `File.Create` returns a string as does `new FileStream`. The code `new FileStream` is wrapped in a `using` block with ensures the stream is disposed when the code exists the block. In your referenced question the OP does not do this hence the exception in that case. – Igor Dec 13 '16 at 15:44
  • 1
    Food for thoughts... In my environment, we are running a backup software which basically keeps track of my filesystem. When new files are created, the backup software kicks in and tries to backup the file almost instantly. I have had instances where my program would create a file, and then I'd try to write something in it but it would be locked, in use by another process. Turned out my backup software would grab the file in that split second between me creating the file, and me trying to write something in it. – blaze_125 Dec 13 '16 at 15:45
  • I understand the difference - but if the file *is being written to* during code execution, but has open handles at the end, I still think suggesting that he change the `FileStream` entirely to test that this code snippet is responsible to instead using `WriteAllBytes` may yield a result. – gravity Dec 13 '16 at 15:47
  • @blaze_125 - in the comments the OP mentioned `If I stop execution and start it again, it works fine`. Maybe there is a race condition but maybe not. Either way good idea. – Igor Dec 13 '16 at 15:47
  • 1
    Have you tried looking in Process Explorer to see what's locking it? – EJoshuaS - Stand with Ukraine Dec 13 '16 at 16:19
  • How does the image get to the clipboard? Is it possible that that's causing the file to be locked (e.g. if the user has it open or something)? – EJoshuaS - Stand with Ukraine Dec 13 '16 at 16:23
  • 3
    Please forgive me, I'm a moron. :) I had another snippet of code in there that I forgot it was executing that was getting the properties of the BMP from the file, and THAT part of opening a new Bitmap object and didn't have a "using" around it. Sorry for all the trouble. – Starfleet Security Dec 13 '16 at 16:28

1 Answers1

0

If the file is already locked before your program runs, you won't be able to open it. See if you can unlock it using a program like Unlocker. Once the file is unlocked, you should be able to open it again.

When you wrap the file streams into a using{} statement, the close(); and dispose(); calls are not necessary. They are done for you as the code exits the using{} statement. It doesn't hurt to call close(); but it is redundant. If you call dispose(); however, and the end of the using calls dispose(); too, you will likely get an exception because you're calling dispose(); on a disposed object. Remove your calls to close(); and dispose();

If you 'end process' on your program via Task Manager (mangler) or click the 'stop' button inside your IDE while the program was looping inside the using{} block, it will lock the file again and you'll need to use 'Unlocker' again.

So, remove your close() and dispose() calls and then use 'Unlocker' to unlock the file. Run your program, and you should be golden...

UPDATE:

Put a try/catch block around the following code:

        bmp.Save(memory, ImageFormat.Bmp);
        byte[] bytes = memory.ToArray();
        fs.Write(bytes, 0, bytes.Length);

See if you ever get an exception in the above chunk of code. If you put a try/catch around it, it might point to to why the problem is happening..

Curtis
  • 5,794
  • 8
  • 50
  • 77
  • The file doesn't even exist before I run my program, I'm creating it. I understand the "using" does all that for me, I only added those for absolute certainty and because I'm banging my head against the wall trying to figure out why this isn't working as it should. I'm not getting an error from those extra calls. But I've removed them, and I'm still getting the same error on the second attempt. – Starfleet Security Dec 13 '16 at 15:37
  • Please see my updates above. Perhaps a try/catch could shed some light on the solution.. – Curtis Dec 13 '16 at 20:08