2010-09-27 9 views
2

Фрагмент кода должен был просто написать строку в текстовый файл «all_results.txt». У меня были ошибки в File.WriteAllText. После поиска сети для решений я попытался использовать FileStream и StreamWriter в качестве замены. Проблема все еще сохраняется.C# Процесс не может получить доступ к файлу '' ', потому что он используется другим процессом.

Это дало мне:

IOException Необработанное: Процесс не может получить доступ к файлу 'C: \ Users \ MadDebater \ Desktop \ ConsoleTest1 \ ConsoleTest \ Bin \ Debug \ all_results.txt', потому что он используется другим обработать.

Странно, ошибки возникают произвольно. Это может быть во время третьего цикла или 45-го цикла, прежде чем он попадет в ошибку. Я предоставил полный код для этого класса, если проблема глубже, чем кажется. Я уверен, что это не имеет никакого отношения к моему антивирусному сканеру или тому подобному.

try 
       { 
        using (FileStream stream = new FileStream(@"all_results.txt", FileMode.Create)) // Exception here 
       { 
        using (StreamWriter writer = new StreamWriter(stream)) 
        { 
         writer.WriteLine(result); 
         writer.Dispose(); 
         writer.Close(); 
        } 

        stream.Dispose(); 
        stream.Close(); 
       } 

       } 
       catch (IOException ex) 
       { 
        Console.WriteLine(ex); 
       } 

Даже когда я пытаюсь это сделать, он все еще терпит неудачу.

try 
       { 
        File.WriteAllText(@"all_results.txt", result); // Exception here 
       } 
       catch (IOException ex) 
       { 
        Console.WriteLine(ex.Message); 
       } 

Ниже приведен полный код для класса. Он предназначен для включения в список твитов Twitter и классифицировать их с помощью классификации байесов по одному.

using System; 
    using System.IO; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using BayesClassifier; 
    using System.Text.RegularExpressions; 

    namespace ConsoleTest 
    { 
     class Analyzer 
     { 
      public static void Analyzing(List<string> all_results) 
      { 

      Reducting(all_results); 
      Classifying(); 
     } 

     public static void Reducting(List<string> all_results) 
     { 
      //Reductor 
      //Precondition: List<string> results 
      all_results.ForEach(delegate(String text) 
      { 

       const string ScreenNamePattern = @"@([A-Za-z0-9\-_&;]+)"; 
       const string HashTagPattern = @"#([A-Za-z0-9\-_&;]+)"; 
       const string HyperLinkPattern = @"(http://\S+)\s?"; 
       string result = text; 

       if (result.Contains("http://")) 
       { 
        var links = new List<string>(); 
        foreach (Match match in Regex.Matches(result, HyperLinkPattern)) 
        { 
         var url = match.Groups[1].Value; 
         if (!links.Contains(url)) 
         { 
          links.Add(url); 
          result = result.Replace(url, String.Format("")); 
         } 
        } 
       } 

       if (result.Contains("@")) 
       { 
        var names = new List<string>(); 
        foreach (Match match in Regex.Matches(result, ScreenNamePattern)) 
        { 
         var screenName = match.Groups[1].Value; 
         if (!names.Contains(screenName)) 
         { 
          names.Add(screenName); 
          result = result.Replace("@" + screenName, 
           String.Format("")); 
         } 
        } 
       } 

       if (result.Contains("#")) 
       { 
        var names = new List<string>(); 
        foreach (Match match in Regex.Matches(result, HashTagPattern)) 
        { 
         var hashTag = match.Groups[1].Value; 
         if (!names.Contains(hashTag)) 
         { 
          names.Add(hashTag); 
          result = result.Replace("#" + hashTag, 
           String.Format("")); 
         } 
        } 
       } 

       // Write into text file 
/* 
       try 
       { 
        using (FileStream stream = new FileStream(@"all_results.txt", FileMode.Create)) // Exception here 
       { 
        using (StreamWriter writer = new StreamWriter(stream)) 
        { 
         writer.WriteLine(result); 
         writer.Dispose(); 
         writer.Close(); 
        } 

        stream.Dispose(); 
        stream.Close(); 
       } 

       } 
       catch (IOException ex) 
       { 
        Console.WriteLine(ex); 
       } 
       */ 
       try 
       { 
        File.WriteAllText(@"all_results.txt", result); // Exception here 
       } 
       catch (IOException ex) 
       { 
        Console.WriteLine(ex.Message); 
       } 

      }); 
     } 

     public static void Classifying() 
     { 
      // Classifying 

      BayesClassifier.Classifier m_Classifier = new BayesClassifier.Classifier(); 


      m_Classifier.TeachCategory("Positive", new System.IO.StreamReader("POSfile.txt")); 
      m_Classifier.TeachCategory("Negative", new System.IO.StreamReader("NEGfile.txt")); 

      Dictionary<string, double> newscore; 
      newscore = m_Classifier.Classify(new System.IO.StreamReader("all_results.txt")); 

      PrintResults(newscore); 
} 

     public static void PrintResults(Dictionary<string, double> newscore) 
     { 
      foreach (KeyValuePair<string, double> p in newscore) 
      { 
       Console.WriteLine(p.Key + ", " + p.Value); 
      } 

      List<string> list = new List<string>(); 
      using (StreamReader reader = new StreamReader("all_results.txt")) 
      { 
       string line; 
       while ((line = reader.ReadLine()) != null) 
       { 
        list.Add(line);   // Add to list. 
        Console.WriteLine(line); // Write to console. 

       } 

       reader.Close(); 
      } 

      //PrintSentiment(newscore); 
     } 

     public static void PrintSentiment(Dictionary<string, double> newscore) 
     { 

      // if difference < 2, neutral 
      // if neg < pos, pos 
      // if pos < neg, neg 

      double pos = newscore["Positive"]; 
      double neg = newscore["Negative"]; 
      string sentiment = ""; 

      if (Math.Abs(pos - neg) < 1.03) 
      { 
       sentiment = "NEUTRAL"; 
      } 
      else 
      { 
       if (neg < pos) 
       { 
        sentiment = "POSITIVE"; 
       } 
       else if (pos < neg) 
       { 
        sentiment = "NEGATIVE"; 
       } 
      } 

      Console.WriteLine(sentiment); 


      // append tweet_collection to final_results <string> list 
      // append sentiment tag to the final_results <string> list 
      // recursive 
     } 
    } 
} 
+0

По какой причине вы не используете TextWriter? – w69rdy

+1

Также я нашел ошибки, подобные этому в прошлом, при записи в текстовый файл в узком цикле. Файл не будет выпущен вовремя для следующей итерации, чтобы использовать его, и это может быть проблемой, особенно если есть много текста для записи. – w69rdy

+0

@ w69rdy Не знаком с TextWriter. Существует ли решение проблемы с узким контуром? – youngscientist

ответ

2

используйте утилиту, подобную filemon, чтобы проверить, какие процессы используют файл.

ОБНОВЛЕНИЕ: Из того, что я прочитал Монитор процесса очень похож на filemon. из любого из этих инструментов вы можете найти, какой процесс обратился к вашему файлу в какой момент. вы можете добавить фильтр для своего файла, прежде чем вы начнете мониторинг.

Другая вещь, которую вы могли бы попробовать, - это заблокировать файл, если он существует.

+0

Filemon больше не поддерживается в Windows в соответствии с поиском google. Я попробовал Process Monitor, но я не уверен, как определить, какой процесс использует файл. Объяснить? – youngscientist

+1

Вам нужен Process Explorer. Запустите его, нажмите CTRL-F и введите часть имени файла, он покажет вам все дескрипторы, соответствующие имени. – flatline

+0

проверить обновление, чтобы ответить –

1

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

+0

Отключить сканер вирусов, Google Desktop и служба индексирования окон. Не повезло. – youngscientist

0

Попробуйте записать файл в другой каталог за пределами папки отладки.

+0

Пробовал использовать c: /all_results.txt – youngscientist

0

Просто «дикий выстрел» - помогает ли вам разместить файл в более предсказуемом месте, например, «c: \ all_results.txt»?

+0

Пробовал это. Не повезло. – youngscientist

0

попробуйте поставить Thread.Sleep (1000) в вашу петлю. Как и кто-то, упомянутый выше, файл не всегда освобождается вовремя для следующей итерации цикла.

+0

Пробовал это. Не повезло. – youngscientist

3

Dont вызывать Dispose() и Close() в FileStream и StreamWriter, это будет обрабатываться автоматически с помощью предложения use.

+0

Даже если я просто использую код File.WriteAllText(), который не использует методы Dispose() и Close(), проблема сохраняется. – youngscientist

+0

StreamReader также закрывается вручную в методе PrintResults. Попробуйте без этого вызова. – Marcus

+0

Да. Это тоже. Не повезло. – youngscientist

0

Как уже отмечалось, открытие и закрытие файла может быть проблемой. Одно из решений, о которых не упоминалось, заключается в том, чтобы сохранить файл открытым на время обработки. После завершения файл может быть закрыт.

+0

Можете ли вы показать мне, как это можно сделать с помощью кода, пожалуйста? Это намного яснее. – youngscientist

+0

Откройте FileStream перед циклом foreach. Внутри вызова цикла .WriteLine(). После завершения foreach закройте FileStream. – Pedro

0

Педро:

Как уже говорилось, открытие и закрытие файла повторно может быть проблемой. Одно из решений, о которых не упоминалось, заключается в том, чтобы сохранить файл открытым на время обработки. После завершения файл может быть закрыт.

Или, наоборот, собирайте текст в StringBuilder или в другом текстовом хранилище в памяти, а затем выгрузите текст в файл после завершения цикла.

+0

Байесовский классификатор принимает файл .txt как вход, к сожалению, поэтому у меня нет выбора. Сбрасывание всего этого не даст мне классификации для 1 щебетать Twitter. – youngscientist

+1

Затем вы можете попробовать написать один твит на файл, чтобы не было написано 2 итерации в один и тот же файл. Все это делается для того, чтобы предоставить ОС достаточно времени, чтобы закрыть файл и выпустить его дескриптор. Знание всех имен файлов, которые вы написали, позволяет вам кормить их один за другим в классификаторе. – bugventure

+0

Хорошая точка в памяти, являющаяся еще одной альтернативой повторной записи файлов. – Pedro

0

Я нашел сообщение, пока у меня была аналогичная проблема. Данные советы дали мне идею! Так что для этой цели я написал следующий метод

public static void ExecuteWithFailOver(Action toDo, string fileName) 
{ 

    for (var i = 1; i <= MaxAttempts; i++) 
    { 
     try 
     { 
      toDo(); 

      return; 
     } 
     catch (IOException ex) 
     { 
      Logger.Warn("File IO operation is failed. (File name: {0}, Reason: {1})", fileName, ex.Message); 
      Logger.Warn("Repeat in {0} milliseconds.", i * 500); 

      if (i < MaxAttempts) 
       Thread.Sleep(500 * i); 
     } 
    } 

    throw new IOException(string.Format(CultureInfo.InvariantCulture, 
             "Failed to process file. (File name: {0})", 
             fileName)); 

} 

тогда я использовал метод следующим образом

Action toDo =() => 
        { 
         if (File.Exists(fileName)) 
          File.SetAttributes(fileName, FileAttributes.Normal); 

         File.WriteAllText(
          fileName, 
          content, 
          Encoding.UTF8 
          ); 
        }; 

    ExecuteWithFailOver(toDo, fileName); 

Позже анализа журналов я обнаружил, что причина моих бед была попытка действовать против того же файла из параллельных потоков. Но я все еще вижу некоторые pro-s в использовании предлагаемого метода FailOver

Смежные вопросы

 Смежные вопросы