我有两个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;
}
现在,当我尝试将这两个应用程序放在一起时,我得到一个异常,说“未处理的异常:System.IO.IOException:进程无法访问该文件,因为它正被另一个进程使用”。
我为ReadWrite访问设置了两个文件流,我为FileAccess.Write设置了一个文件流,为FileAccess.Read设置了另一个。
为什么我会得到这个例外的任何线索?
由于 HEW。
答案 0 :(得分:7)
lines = File.ReadAllLines(args [1] +“\ Chat.log”)。长度;
有你的问题。该方法打开文件,读取所有行并再次关闭它。它在打开文件FileShare.Read时使用“普通”文件共享设置。 拒绝对任何其他也打开文件的进程的写访问权。
这在这里不起作用,你已经使用写访问权限打开了文件。第二个过程不能否认它。 IOException就是结果。
您不能在这里使用File.ReadAllLines(),您需要使用FileShare.ReadWrite打开FileStream,将其传递给StreamReader并读取所有行。
要注意你在这里遇到的非常麻烦的种族潜力,不能保证你读到的最后一行是完整的一行。只获得\ r而不是行尾的\ n是一个特别棘手的问题。这将随机发生,不经常发生,是最难以排除故障的错误。也许你的Flush()调用修复了它,我从来没有足够的勇气将它用于测试。
答案 1 :(得分:4)
在这种情况下,允许第二个程序 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++;
}
}
答案 2 :(得分:1)
MSDN提供两种不获得独占保留的方法:
FileStream对象没有 当它处理时独占 SafeFileHandle属性是 访问以暴露句柄或 给出了FileStream对象 其中的SafeFileHandle属性 构造
文档暗示反之亦然:
在不设置SafeFileHandle的情况下打开FileStream意味着 FileStream维护文件句柄的独占保持(即 内联应该抛出的IO异常。)
答案 3 :(得分:1)
StreamReader sr = new StreamReader("f:\\watch\\input.txt");
input.txt可能无法阅读?
在第一个应用程序中也使用using
语句而不是Close()(如果抛出异常)。
否则就可以了。文件共享可能需要额外的权限(不能真正影响它)。
我错过了一段代码:
int newlines = File.ReadAllLines(path).Length;
将stream
与StreamReader
一起使用。