2009-05-18 4 views
3

XML 파일 (old.xml)을 열고 잘못된 문자를 필터링하고 다른 XML 파일 (abc.xml)에 작성하는 코드입니다. 마지막으로 XML (abc.xml)을 다시로드합니다. followling 라인을 실행할 때, 예외, xml 파일이 다른 프로세스에 의해 사용이 말한다되어내 코드에서 누수가 어디 있습니까?

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

사람이 무슨 어떤 생각을 가지고 있습니까? 내 코드의 누수와 왜 (항상 "사용"키워드를 사용하여 누수가 있는지 혼란 스럽습니다 ...)?

여기 내 모든 코드가 있는데, Windows Vista x64에서 C# + VSTS 2008을 사용하고 있습니다.

// 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 : 버퍼 크기를 10M에서 1M으로 변경하려고 시도했습니다. 나는 너무 혼란 스럽다. 어떤 생각?

EDIT2 : 입력 된 XML 파일이 100M 또는 그와 같이 매우 큰 경우이 문제가 재현하기가 쉽습니다. .Net 알려진 버그인지 여부를 의심하고 있습니다. ProcessExplorer/ProcessMonitor와 같은 도구를 사용하여 XmlDocument.Load가 액세스하지 못하도록 파일을 잠그는 프로세스를 확인합니다.

+0

큰 버퍼가 필요한 이유는 무엇입니까? (문제와 관련해서는 안되지만, 왜 10MB인지를 아는 것은 흥미로울 것입니다 ...). 나는 아마도 10k를 사용할지도 모른다 ... –

+0

나는 10M에서 1M까지 버퍼의 크기를 변경하려고 노력했다. 나는 너무 혼란 스럽다. 어떤 생각? – George2

+0

원래의 코드에서 큰 버퍼 크기를 사용하는 것은 순전히 목적을 테스트하는 것입니다. 즉, 임의로 설정 한 것이 아닌 임시 값입니다. – George2

답변

1

버퍼가 할당 해제되지 않습니까?

+0

CLR이 모든 메모리 버퍼를 관리한다고 생각합니다. 혼란스러워. 어쨌든, 당신의 제안 된 수정은 무엇입니까? 코드를 보여 주시겠습니까? – George2

+0

버퍼를 할당 해제 할 필요는 없습니다 (그리고 실제로 메커니즘이 없습니다). GC는 곧 GEN0에서 (아마도 매우 싸게) 가져올 것입니다. –

+0

요점은 버퍼가 스택에 대해 커야하므로 대형 오브젝트 힙에 압축되어 있습니다. 프로세스가 실행되는 동안 결코 컴팩트하지는 않습니다. –

1

코드가 정상적으로 작동합니다. 방금 확인 했어.

+0

이상한 아이디어가 있습니까? – George2

+0

Nope ... 워크 스테이션 때문에 문제가 발생한 것 같습니다. 코드가 작동하므로 수정 구슬 만이 나를 도울 수 있습니다. –

4

나를 위해 잘 작동합니다. 순수하게 추측 할 수는 있지만 바이러스 검사 프로그램이 파일을 검사하고 있습니까? 조사하려면 바이러스 검사기를 비활성화하고 작동하는지 확인한 다음 바이러스 검사기를 다시 활성화하십시오. 여담으로

, 그것은 파일을 열어 떠날 수있는 하나 개의 방법이 다음 StreamReader 생성자가 예외를 throw하는 경우; 하지만 당신은 어쨌든 XmlDocument 물건에 도달 ...하지만 고려하지 않을 것이다 :

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

지금 fsnew StreamWriter(...)가 발생 가장자리의 경우에 배치된다. 그러나, 나는 이 아니라이 여기에 문제가 있다고 생각합니다.

+0

버퍼 크기를 10M에서 1M으로 변경하려고 시도했습니다! 나는 너무 혼란 스럽다. 어떤 생각? – George2

1

을 사용하는 경우 Dispose을 호출하지만 Dispose은 쓰기 스트림에서 닫을까요? 그렇지 않은 경우에도 시스템은 파일을 쓰기 위해 열어 볼 수 있다고 간주 할 수 있습니다.

나는 그 using 블록 바로 전에 writer의 닫기를 넣으려고합니다.

편집 : 그냥 코드를 직접 사용해 보았습니다. 당신이보고있는 문제없이 컴파일하고 실행했습니다. 다른 사람들이 언급 한 것처럼 바이러스 스캐너를 끄고 파일이 열린 상태에서 창가가 없는지 확인하십시오.

+1

Close()는 Dispose() 호출로 구현되고 StreamReader 또는 StreamWriter를 닫으면 기본 스트림이 닫힙니다. 그래서 이것은 도움이되지 않습니다. –

1

다른 프로세스가 파일에 액세스하려고 시도하지 않았 음을 확인 했습니까?

+0

10M에서 1M으로 버퍼 크기를 변경하려고 시도했습니다! 나는 너무 혼란 스럽다. 어떤 생각? – George2

2

아마도 루트에서 FileSystemWatcher를 실행하고 있습니까?

ProcessMonitor를 사용하여 누가 해당 파일에 액세스하는지 확인할 수도 있습니다.

+0

FileSystemWatcher? 너 무슨 뜻이야? – George2

+0

FileSystemWatcher 클래스입니다. – leppie

+0

아니요, 해당 클래스를 명시 적으로 사용하고 있지 않으며 모든 코드를 게시했습니다. 버퍼 크기를 10M에서 1M으로 변경하려고 시도했습니다! 나는 너무 혼란 스럽다. 어떤 생각? – George2

2

문제는 큰 것으로 보이는 char[]입니다. 크기가 너무 크면 스택이 아닌 큰 객체 힙에 위치합니다.따라서 큰 오브젝트 힙은 소프트웨어가 실행되는 동안 압축되지 않습니다. 한 번 할당 된 공간은 다시 사용될 수 없습니다. 이는 메모리 누수처럼 보입니다. 어레이를 작은 덩어리로 나누어보십시오.

+1

나는 버퍼가 너무 크다고 말 하겠지만, 문제 문장과 관련이있다. "예외가 있다는 것은 xml 파일이 다른 프로세스에 의해 사용된다고 말한다". 버퍼 –

+0

작은 버퍼 크기를 사용하면 노력했지만 코드는 문제없이 작동합니다. 크기가 큰 버퍼로 인해 파일이 닫히지 않게되는 이유는 무엇입니까? 나는 원래 만난 오류가 파일이 닫혀 있지 않다고 생각하니? – George2

+1

이 경우, +1에서 BeowulfOF; 커다란 버퍼가이 문제를 야기한다는 것은 분명하지 않습니다. (사실, 저는 국지적으로 아무런 문제가 없습니다.) 호기심이 생깁니다. OutOfMemoryException, 확실히 ... 파일 잠금? 매우 이상합니다. –

1

일부 사람들에게는 효과가 있고 다른 사람들에게는 효과가 없다는 사실 때문에 파일이 닫히지 않는다고 생각합니다. 파일을로드하기 전에 작성기를 닫으십시오.

+1

파일이 닫히지 않으면 아무에게도 적용되지 않습니다! 이 코드는 파일이 닫혀 있음을 보여줍니다 (이 스레드/프로세스의 범위 내에서 적어도) –

2

나는 누가 파일을 잠그고 있는지를 알기 위해 ProcessMonitor (또는 동등한 것)를 사용하는 두 번째 Leppie의 제안이다. 다른 것은 단지 추측 일뿐입니다.

1

내 생각에는 파일을 닫은 후에 잠그는 바이러스 백신 솔루션을 실행 중입니다. 확인하려면 파일을로드하기 전에 지연 (예 : 1 초)을 추가하십시오. 그게 효과가 있다면 아마도 그 원인을 발견했을 것입니다.

0

실행 Process Explorer

먼저 파일 잠금 프로그램입니다 있는지 확인합니다.

관련 문제