C#文件正由另一个进程使用

我不知道如何解决我的问题。 我不时会收到错误:“进程无法访问文件’xxxx’,因为它正被另一个进程使用”。

这是我发生错误的方法:

private static void write_history(int index, int time_in_sec, int[] sent_resources) { string filepath = "Config\\xxx.txt"; int writing_index = 0; if (File.Exists(filepath)) { System.Threading.Thread.Sleep(5000); StreamReader reader = new StreamReader(new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)); string temp = reader.ReadToEnd(); reader.Close(); for (int i = 0; i < 20; i++) { if (temp.IndexOf("") == -1) { writing_index = i; break; } } } System.Threading.Thread.Sleep(5000); // write to the file StreamWriter writer = new StreamWriter(filepath, true); writer.WriteLine("" + DateTime.Now.AddSeconds(time_in_sec).ToString() + "|" + sent_resources[0] + "|" + sent_resources[1] + "|" + sent_resources[2] + "|" + sent_resources[3] + ""); writer.Close(); } 

我得到的错误:

 ************** Exception Text ************** System.IO.IOException: The process cannot access the file 'Config\\xxx.txt' because it is being used by another process. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath) 

如果您确定正确地打开和关闭文件,最可能的罪魁祸首就是您的病毒检测器。 病毒检测器因观察日志文件已更改,打开它以搜索病毒而臭名昭着,然后在病毒检查程序读取时,尝试写入文件失败。

如果是这种情况,那么我会询问您的病毒检查程序的供应商他们推荐的解决方法是什么。

  1. IDisposable所有对象周围使用。 即使有exception, using将始终调用方法Dispose
  2. 你确实关闭了你的读者,但没有关闭文件流。
  3. 这段代码可以缩短得多,请参阅我答案底部的第二个例子。

     private static void write_history(int index, int time_in_sec, int[] sent_resources) { string filepath = "Config\\xxx.txt"; int writing_index = 0; if (File.Exists(filepath)) { System.Threading.Thread.Sleep(5000); using(FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read) using(StreamReader reader = new StreamReader(stream)) { string temp = reader.ReadToEnd(); } for (int i = 0; i < 20; i++) { if (temp.IndexOf("") == -1) { writing_index = i; break; } } } System.Threading.Thread.Sleep(5000); // write to the file using(StreamWriter writer = new StreamWriter(filepath, true)) { writer.WriteLine("" + DateTime.Now.AddSeconds(time_in_sec).ToString() + "|" + sent_resources[0] + "|" + sent_resources[1] + "|" + sent_resources[2] + "|" + sent_resources[3] + ""); } } 

更短的版本:

  private static void write_history(int index, int time_in_sec, int[] sent_resources) { string filepath = "Config\\xxx.txt"; int writing_index = 0; if (File.Exists(filepath)) { System.Threading.Thread.Sleep(5000); string temp = File.ReadAllText(filepath); for (int i = 0; i < 20; i++) { if (temp.IndexOf("") == -1) { writing_index = i; break; } } } System.Threading.Thread.Sleep(5000); // write to the file File.WriteAllText(filepath, "" + DateTime.Now.AddSeconds(time_in_sec).ToString() + "|" + sent_resources[0] + "|" + sent_resources[1] + "|" + sent_resources[2] + "|" + sent_resources[3] + ""); } 

在multithreading的情况下:

 private static readonly object _syncLock = new object(); private static void write_history(int index, int time_in_sec, int[] sent_resources) { lock(_syncLock) { string filepath = "Config\\xxx.txt"; int writing_index = 0; if (File.Exists(filepath)) { System.Threading.Thread.Sleep(5000); string temp = File.ReadAllText(filepath); for (int i = 0; i < 20; i++) { if (temp.IndexOf("") == -1) { writing_index = i; break; } } } System.Threading.Thread.Sleep(5000); // write to the file File.WriteAllText(filepath, "" + DateTime.Now.AddSeconds(time_in_sec).ToString() + "|" + sent_resources[0] + "|" + sent_resources[1] + "|" + sent_resources[2] + "|" + sent_resources[3] + ""); } } 

我的猜测是你的FileStream (你传递给StreamReader构造函数的那个​​)没有被关闭

 StreamReader reader = new StreamReader(new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)); 

将该语句放在using语句中,以确保所有目的都绑定

 using(StreamReader reader = new StreamReader(new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read))) { //the using statement will handle the closing for you } 

您的方法不是线程安全的。 如果您以multithreading方式访问此方法,则您的线程可能同时尝试访问文件。 除了alexn正确处理StreamReader的答案之外,还要考虑在类中使用方法之外的静态对象,然后在访问文件之前简单地锁定它。

 private static object lockObject = new object(); private static void write_history(int index { lock(lockObject) { // Access file here } } 

您可以使用“使用”,也可以强制垃圾收集器释放所有引用。 这解决了我的问题。 在应用进程级别或线程级别更改之前检查代码。

例:

 using(StreamWriter writer....) { Your Code.... } this.deleteFiles(filepath); 

要么:

 GC.Collect(); this.deleteFiles(filepath);