为什么我在尝试从正在写入的文件中读取时遇到未处理的exception:System.IO.IOException?

我有两个C#应用程序,一个是逐行读取文件(文件A)并将其内容写入另一个文件(文件B)。

第二个应用程序使用文件B的FileSystemWatcher查看它何时更新,并报告差异是程序启动时和文件更改之间的行号。

这就是我现在要做的所有事情,最终我想要读取上次读取文件和当前读取之间的界限,但直到我可以得到保持的线差。

我对应用程序1的代码是;

static void Main(string[] args) { String line; StreamReader sr = new StreamReader("f:\\watch\\input.txt"); FileStream fs = new FileStream("f:\\watch\\Chat.log", FileMode.Create, FileAccess.Write, FileShare.ReadWrite); StreamWriter sw = new StreamWriter(fs); while ((line = sr.ReadLine()) != null) { sw.WriteLine(line); Thread.Sleep(200); Console.WriteLine(line); sw.Flush(); } sw.Close(); sr.Close(); } 

我对应用程序2的代码是;

  public static int lines = 0; public static void Main() { Run(); } public static void Run() { string[] args = System.Environment.GetCommandLineArgs(); if (args.Length != 2) { Console.WriteLine("Usage: Watcher.exe (directory)"); return; } FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Path = args[1]; watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; watcher.Filter = "Chat.log"; watcher.Changed += new FileSystemEventHandler(OnChanged); watcher.EnableRaisingEvents = true; lines = File.ReadAllLines(args[1] + "\\Chat.log").Length; Console.WriteLine("File lines: " + lines); while(Console.Read()!='q'); } private static void OnChanged(object source, FileSystemEventArgs e) { Linework(e.FullPath); Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); } public static string Linework(string path) { string newstring = " "; using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { int newlines = File.ReadAllLines(path).Length; Console.WriteLine("Lines now: " + newlines); } return newstring; } 

现在,当我尝试将这两个应用程序一起运行时,我得到一个exception,说“未处理的exception:System.IO.IOException:进程无法访问该文件,因为它正被另一个进程使用”。

我为ReadWrite访问设置了两个文件流,我为FileAccess.Write设置了一个文件流,为FileAccess.Read设置了另一个。

关于为什么我会得到这个例外的任何线索?

谢谢嘿。

lines = File.ReadAllLines(args [1] +“\ Chat.log”)。Length;

这是你的问题。 该方法打开文件,读取所有行并再次关闭它。 它在打开文件FileShare.Read时使用“普通”文件共享设置。 这会拒绝对也打开文件的任何其他进程的写访问权限。

这在这里不起作用,你已经通过写访问打开了文件。 第二个过程不能否认它。 IOException就是结果。

你不能在这里使用File.ReadAllLines(),你需要用FileShare.ReadWrite打开一个FileStream,将它传递给StreamReader并读取所有行。

要注意你在这里遇到的非常麻烦的种族潜力,不能保证你读到的最后一行是完整的。 只获得\ r而不是行尾的\ n是一个特别棘手的问题。 这将随机发生,不经常发生,是最难解决的错误。 也许你的Flush()调用修复了它,我从来没有勇敢过这个测试。

在这种情况下,允许对文件执行第二个程序ReadWrite访问。

 //lines = File.ReadAllLines(args[1] + "\\Chat.log").Length; //Commenting the above lines as this would again open a new filestream on the chat.log //without the proper access mode required. using (FileStream fsReader = new FileStream(args[1] + "\\Chat.log", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) { using (StreamReader sr = new StreamReader(fsReader)) { while (sr.ReadLine() != null) lines++; } } 
 StreamReader sr = new StreamReader("f:\\watch\\input.txt"); 

input.txt可能无法读取?

在第一个应用程序中也使用using语句而不是Close()(如果抛出exception)。

否则就可以了。 文件共享可能需要额外的权限(不能真正影响)。

我错过了一段代码:

 int newlines = File.ReadAllLines(path).Length; 

streamStreamReader一起使用。

MSDN提供了两种不获得独占保留的方法:

当访问SafeFileHandle属性以暴露句柄或FileStream对象在其构造函数中被赋予SafeFileHandle属性时,FileStream对象将不会在其句柄上具有独占保持。

文档暗示反之亦然:

在不设置SafeFileHandle的情况下打开FileStream意味着FileStream在文件句柄上保持独占保留(它与应该抛出的IOexception内联)。