2009-05-18 1 views
3

Вот мой код, который открывает XML-файл (old.xml), фильтрует недопустимые символы и записывает в другой XML-файл (abc.xml). Наконец, я снова загружу XML (abc.xml). При выполнении followling линии, там говорит исключение файл XML используется другим процессом,где утечка в моем коде?

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

Кто-нибудь есть какие-либо идеи, что не так? Любые утечки в моем коде и почему (я все время использую ключевое слово «using», смущен, чтобы видеть утечки ...)?

Вот мой весь код, я использую C# + VSTS 2008 под 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: Я попытался изменить размер буфера от 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

Нет ... Я думаю, проблема вызвана вашей рабочей станцией. Код работает, поэтому - только хрустальный шар может помочь мне помочь вам. –

4

Это прекрасно работает для меня. Чисто догадаться, но, может быть, проверка вируса сканирует файл? Чтобы проверить, попробуйте отключить проверку вируса и посмотреть, работает ли он (а затем снова активировать средство проверки на вирусы).

В качестве альтернативы, есть один способ: может оставить файл открытым: если конструктор StreamReader выдает исключение; но тогда вы не достигнете XmlDocument вещей в любом случае ... но учтите:

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

fs Теперь расположен в ребре-случае, когда new StreamWriter(...) бросков. Однако, не считают, что здесь проблема.

+0

Я попытался изменить размер буфера от 10M до 1M, и он работает! Я так смущен, какие-то идеи? – George2

1

используя вызовет Dispose, но будет Dispose позвонить близко к потоку записи? Если это не так, система все равно может считать файл открытым для записи.

Я бы постарался положить конец writer как раз перед концом своего блока using.

Редактировать: Просто попробовал сам код. Скомпилирован и работает без проблем, которые вы видите. Попробуйте отключить антивирусные сканеры, как упомянули некоторые другие, и убедитесь, что у вас нет окна где-то с открытым файлом.

+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

I второе предложение Leppie использовать ProcessMonitor (или эквивалент), чтобы точно видеть, кто блокирует файл. Все остальное - просто спекуляция.

1

Моя ставка заключается в том, что у вас есть антивирусное решение, которое блокирует файл после его закрытия. Чтобы проверить, попробуйте добавить задержку (например, 1 секунду) перед загрузкой файла. Если это работает, вы, вероятно, нашли причину.