11

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.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Scriptworks
  • 495
  • 1
  • 6
  • 10
  • Do some of the Images have the same ImageName and ImageExtension? – Bob Horn Nov 11 '12 at 20:57
  • Are you sure, is the path newPath exists? – Hamlet Hakobyan Nov 11 '12 at 20:59
  • 2
    delete `File.Create(newPath);` and try. File.WriteAllBytes: `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.` http://msdn.microsoft.com/en-us/library/system.io.file.writeallbytes.aspx – Nesim Razon Nov 11 '12 at 21:00
  • You do not dispose stream created by File.Create. So it is still using that file. Tim's answer is correct – Mariusz Nov 11 '12 at 22:22

7 Answers7

25

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.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
5

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

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
2
using (FileStream fs = 
new FileStream(filePath,
    FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

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

Ashwin Patil
  • 1,307
  • 1
  • 23
  • 27
1

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);
                }
arserbin3
  • 6,010
  • 8
  • 36
  • 52
just.another.programmer
  • 8,579
  • 8
  • 51
  • 90
0

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?

Hamlet Hakobyan
  • 32,965
  • 6
  • 52
  • 68
0

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.

Lawrence Johnson
  • 3,924
  • 2
  • 17
  • 30
-3

Force the garbage collector to clean.

GC.Collect();
Pang
  • 9,564
  • 146
  • 81
  • 122
NoloMokgosi
  • 1,678
  • 16
  • 10