Where is the leak in my code?

Here is my code that opens the XML file (old.xml), filters the invalid characters and writes to another XML file (abc.xml). Finally, I will reload the XML (abc.xml). When executing the followling line, there is an exception indicating that the xml file is being used by another process,

xDoc.Load("C:\\abc.xml"); 

Does anyone have any idea what is wrong? Any leaks in my code and why (I always use the keyword "using", confused to see leaks ...)?

Here is my whole code, I am using C # + VSTS 2008 under Windows Vista x64.

  // Create an instance of StreamReader to read from a file. // The using statement also closes the StreamReader. Encoding encoding = Encoding.GetEncoding("utf-8", new EncoderReplacementFallback(String.Empty), new DecoderReplacementFallback(String.Empty)); using (TextWriter writer = new StreamWriter(new FileStream("C:\\abc.xml", FileMode.Create), Encoding.UTF8)) { using (StreamReader sr = new StreamReader( "C:\\old.xml", encoding )) { int bufferSize = 10 * 1024 * 1024; //could be anything char[] buffer = new char[bufferSize]; // Read from the file until the end of the file is reached. int actualsize = sr.Read(buffer, 0, bufferSize); writer.Write(buffer, 0, actualsize); while (actualsize > 0) { actualsize = sr.Read(buffer, 0, bufferSize); writer.Write(buffer, 0, actualsize); } } } try { XmlDocument xDoc = new XmlDocument(); xDoc.Load("C:\\abc.xml"); } catch (Exception ex) { Console.WriteLine(ex.Message); } 

EDIT1: I tried resizing the buffer from 10M to 1M and it works! I'm so confused, any ideas?

EDIT2: I find this problem very easy to reproduce when the input old xml file is very large, like 100M or something like that. I suspect this is a known .Net bug? I am going to use tools like ProcessExplorer / ProcessMonitor to find out which process is blocking the file so that it does not access XmlDocument.Load.

+3
c # file memory-leaks
source share
11 answers

This works great for me. Purely guessed, but maybe a virus scan scans the file? To research, try disabling the virus scan and see if it works (and then turning on the virus scan again).

Aside, there is one way in which it can leave the file open: if the StreamReader constructor throws an exception; but then you still won't reach the XmlDocument stuff ... but think about it:

 using (FileStream fs = new FileStream("C:\\abc.xml", FileMode.Create)) using (TextWriter writer = new StreamWriter(fs, Encoding.UTF8)) { ... } 

Now fs is located in the edge case, where new StreamWriter(...) thrown away. However, I do not think this is a problem here.

+4
source share

Perhaps you are using FileSystemWatcher in the root?

You can also use ProcessMonitor to find out who is accessing this file.

+2
source share

The problem is your char[] , which seems big. If it is too large, it is located on a large object heap, and not on the stack. Consequently, a bunch of large objects are not compacted as long as the software is running, once the allocated space may not be used again - this is similar to a memory leak. Try splitting your array into smaller pieces.

+2
source share

I Leppie’s second suggestion is to use ProcessMonitor (or equivalent) to see exactly who is locking the file. Everything else is just speculation.

+2
source share

Your buffer is not freed, right?

+1
source share

The code is working fine. Just verified.

+1
source share

will call Dispose , but will Dispose close the call in the write stream? If this is not the case, the system can still consider the file open for writing.

I will try to end the writer immediately before its end using .

Edit: Just tried the code itself. Compiled and working without the problems you see. Try disabling anti-virus scanners, as mentioned above, and make sure that you do not have a window somewhere with an open file.

+1
source share

Have you verified that no other process is trying to access the file?

+1
source share

The fact that it works for some people and not for others makes me think that the file is not closing. Close the device before attempting to download the file.

+1
source share

My bet is that you have an anti-virus solution that blocks the file after it is closed. To check, try adding a delay (for example, 1 second) before downloading the file. If this works, you probably found the reason.

+1
source share

Launch Process Explorer

Make sure your program locks the file first.

0
source share

All Articles