C# Процесс не может получить доступ к файлу ''', потому что он используется другим процессом
Фрагмент кода должен был просто записать строку в текстовый файл с именем "all_results.txt". У меня были ошибки реализации в File.WriteAllText. После поиска решений в сети я попытался использовать FileStream и StreamWriter в качестве заменителей. Проблема все еще сохраняется.
Это дало мне:
IOException Unhandled: процесс не может получить доступ к файлу 'C:\Users\MadDebater\Desktop\ConsoleTest1\ConsoleTest\bin\Debug\all_results.txt', поскольку он используется другим процессом.
Странно, ошибки происходят произвольно. Это может быть во время 3-го цикла или 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);
}
Ниже приведен полный код класса. Он предназначен для составления списка твитов в Твиттере и их классификации по Байесу.
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
}
}
}
10 ответов
Не вызывайте Dispose() и Close() для FileStream и StreamWriter, это будет автоматически обработано предложением using.
Используйте утилиту наподобие filemon, чтобы проверить, какие процессы используют файл.
ОБНОВЛЕНИЕ: Из того, что я прочитал, Process Monitor очень похож на filemon. Из любого из этих инструментов вы можете узнать, какой процесс в какой момент получил доступ к вашему файлу. Вы можете добавить фильтр для вашего файла, прежде чем начать мониторинг.
другая вещь, которую вы можете попробовать, это получить блокировку файла, если он существует.
Может быть, файл доступен для антивирусного сканера или службы индексации Windows?
Попробуйте поместить Thread.Sleep(1000) в свой цикл. Как кто-то упоминал выше, файл не всегда выпускается вовремя для следующей итерации цикла.
Я нашел сообщение, пока у меня была похожая проблема. Данные советы дали мне представление! Поэтому для этой цели я написал следующий метод
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);
Позже, проанализировав журналы, я обнаружил, что причиной моих проблем была попытка действовать против того же файла из параллельных потоков. Но я все еще вижу некоторые плюсы в использовании предложенного метода FailOver
Попробуйте использовать блокировку вокруг ваших файловых операций. http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
Педро:
Как уже говорили другие, проблема может заключаться в том, чтобы повторно открывать и закрывать файл. Одно из упомянутых решений заключается в том, чтобы файл оставался открытым на время обработки. После завершения файл может быть закрыт.
Или, в качестве альтернативы, соберите свой текст в StringBuilder или какое-либо другое хранилище текста в памяти, а затем выведите текст в файл после завершения цикла.
Просто "дикий выстрел" - поможет ли это, если вы поместите файл в более предсказуемое место, например, "c:\all_results.txt"?
Попробуйте записать файл в другой каталог за пределами папки отладки.
Как уже говорили другие, проблема может заключаться в том, чтобы повторно открывать и закрывать файл. Одно из упомянутых решений заключается в том, чтобы файл оставался открытым на время обработки. После завершения файл может быть закрыт.