natli
natli

Reputation: 3822

BinaryWriter in loop causes "file is being used by another process" error even though it is closed and 'using'

Title sais it all really.

private bool addToBinary(byte[] msg, string filepath)
{
    bool succ = false;

    do
    {
        try
        {
            using (Stream fileStream = new FileStream(filepath, FileMode.Append, FileAccess.Write, FileShare.None))
            {
                using (BinaryWriter bw = new BinaryWriter(fileStream))
                {
                    bw.Write(msg);

                    bw.Flush();
                    fileStream.Flush();
                    bw.Close();
                }
            }
            succ = true;
        }
        catch (IOException ex) { Console.WriteLine("Write Exception (addToBinary) : " + ex.Message); }
        catch (Exception ex) { Console.WriteLine("Some Exception occured (addToBinary) : " + ex.Message); return false; }
    } while (!succ);
    return true;
}

(bw.close also closes the underlying stream)

Using this in any loop causes an output such as;

A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
Write Exception (addToBinary) : The process cannot access the file 'C:\test\test.png' because it is being used by another process.

The bigger the file gets, the more of these errors pop up. It does get through eventually but it significantly reduces file writing speed. It's the Stream fileStream = bit that causes the exception.

What did I do wrong?

Example usage;

do
{
    serverStream = clientSocket.GetStream();
    bytesRead = serverStream.Read(inStream, 0, buffSize); //How many bytes did we just read from the stream?

    recstrbytes = new byte[bytesRead]; //Final byte array
    Array.Copy(inStream, recstrbytes, bytesRead); //Copy from inStream to the final byte array
    addToBinary(recstrbytes, @"C:\test\test.png"); //Append final byte array to binary
    received += recstrbytes.Length; //Increment bytes received
}while (received < filesize);

Upvotes: 1

Views: 1775

Answers (2)

Samuel Parkinson
Samuel Parkinson

Reputation: 3112

Some good advice style wise for those stacked using statements. When you start using more than one it is often neater to use the following style:

using (Stream fileStream = new FileStream(filepath, FileMode.Append, FileAccess.Write, FileShare.None))
using (BinaryWriter bw = new BinaryWriter(fileStream))
{
    bw.Write(msg);
    bw.Flush();
    fileStream.Flush();
    bw.Close();
}

I'm afraid I can't solve your question though, but I'm not sure how much of a good an idea it is to repeatedly try and write to the stream if it isn't successful the first time round.

Upvotes: 1

Dinesh
Dinesh

Reputation: 3770

You need to first check if you can access the file before using Stream to read the file.

You can have a look at this link :

Best way to handle errors when opening file

Have a look at the answers Although I posted my answer

https://stackoverflow.com/a/9503939/448407 but you can look at the post marked as answer.

Only read the file contents if you can access the file and I think it will then work.

Upvotes: 1

Related Questions