"The process cannot access the file because it is being used by another process" with Images

StackOverflow https://stackoverflow.com/questions/13335349

  •  28-11-2021
  •  | 
  •  

Question

I've seen many issues like this that have been solved and the problem was mostly due to streams not being disposed of properly.

My issue is slightly different, here follow a code snippet

 foreach (Images item in ListOfImages)
 {
      newPath = Path.Combine(newPath, item.ImageName + item.ImageExtension);
      File.Create(newPath);

      File.WriteAllBytes(newPath, item.File);
 }

Where Images is a custom struct and item.File is the raw data, byte[].

My issue is that at the line where the WriteAllBytes is called, an exception is thrown. The message reads:

The process cannot access the file because it is being used by another process

Again I have no clue how am I going to somehow close the process.

Was it helpful?

Solution

Since File.Create returns the stream i would dispose it properly:

using(var stream = File.Create(newPath)){}
File.WriteAllBytes(newPath, item.File);

or you can use the stream to write to the file directly:

using (FileStream fs = File.Create(newPath))
{
    fs.Write(item.File, 0, item.File.Length);
}

or, probably the easiest, use File.WriteAllBytes alone:

File.WriteAllBytes(newPath, item.File);

Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.

OTHER TIPS

You state that your problem has nothing to do with disposing streams but check this MSDN article:

http://msdn.microsoft.com/en-us/library/d62kzs03.aspx

What does File.Create return? A FileStream!!!!

And, at the end of the day, why are you using File.Create if File.WriteAllBytes creates a file if this doesn't exist? ;)

Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.

Check it on MSDN too: http://msdn.microsoft.com/en-us/library/system.io.file.writeallbytes.aspx

using (FileStream fs = 
new FileStream(filePath,
    FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

Your log may be write locked, so try with FileShare.ReadWrite.

The create method opens the file for writing and returns a FileStream object for you to work with. Just because you are not referencing it does not mean it does not need to be returned.

foreach (Images item in ListOfImages)
                {
                    newPath = Path.Combine(newPath, item.ImageName + item.ImageExtension);
                    FileStream f = File.Create(newPath);

                    f.Write(item.File, 0, item.File.Length);
                }

The File.WriteAllBytes creates the file if necessary. You can juts use:

foreach (Images item in ListOfImages)
{
    newPath = Path.Combine(newPath, item.ImageName + item.ImageExtension);
    File.WriteAllBytes(newPath, item.File);
}

And are you combine path correctly?

This is the most specific way to accomplish what you are trying to do:

foreach (Images item in ListOfImages)
{
    using (System.IO.FileStream output = new System.IO.FileStream(Path.Combine(newPath, item.ImageName + item.ImageExtension),
        System.IO.FileMode.Create, System.IO.FileAccess.Write))
    {
        output.Write(item.File, 0, item.File.Length);
        output.Flush();
        output.Close();
    }
}

You also need to fix your logic for creating the path, which I have done in my example above. You were concatenating the newPath over and over again.

Force the garbage collector to clean.

GC.Collect();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top