尝试从正在写入的文件读取时,为什么会出现未处理的异常:System.IO.IOException? [英] Why am I getting a Unhandled Exception: System.IO.IOException when trying to read from a file being written to?

查看:529
本文介绍了尝试从正在写入的文件读取时,为什么会出现未处理的异常:System.IO.IOException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

第二个应用程序正在使用FileSystemWatcher for File B来查看它何时更新,并报告程序启动时间和文件更改时间之间的行号是不同的.

这就是我现在要做的所有事情,最终我想读取文件的最后读取时间与当前读取时间之间的界限,但是直到获得保留的行差异为止.

我对应用程序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的文件流设置.

关于我为什么会收到此异常的任何线索?

谢谢 w.

解决方案

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

有问题.该方法将打开文件,读取所有行,然后再次将其关闭.打开文件FileShare.Read时,它将使用常规"文件共享设置.该否认写入也打开了文件的任何其他进程的访问权限.

这在这里不起作用,您已经使用写访问权打开了该文件.第二进程不能拒绝它. IOException是结果.

您不能在这里原样使用File.ReadAllLines(),需要使用FileShare.ReadWrite打开FileStream,将其传递给StreamReader并读取所有行.

请注意,您在这里可能会遇到非常麻烦的比赛潜力,因此无法保证您将阅读的最后一行是完整的行.在行尾仅获取\ r而不是\ n是一个特别棘手的问题.这将随机地,不频繁地打击,这是最难解决的错误.也许您的Flush()调用可以解决此问题,但我从来没有足够勇敢地对此进行过测试.

I have two C# applications, one is reading a file (File A) line by line and writing its contents to a different file (File B).

The second application is using FileSystemWatcher for File B to see when it is updated and reporting the difference is line numbers between when the program was started and when the file was changed.

Thats all I am trying to do for now, ultimately I want to read the lines between when the file was last read and the current read but until I can get the line difference that is on hold.

The code that I have for application 1 is;

        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();

    }

The code that I have for application 2 is;

        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;

}

Now when I try and run these two applications together I get an exception saying "Unhandled Exception: System.IO.IOException: The process cannot access the file because it is in use by another process".

I have both filestreams setup for ReadWrite access and I have one of the filestreams setup for FileAccess.Write and the other for FileAccess.Read.

Any clues as to why I would be getting this exception?

Thanks Hew.

解决方案

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

There's your problem. That method opens the file, reads all the lines and closes it again. It uses "normal" file share settings when opening the file, FileShare.Read. That denies write access to any other process that also has the file opened.

That cannot work here, you've already have the file opened with write access. The 2nd process cannot deny it. The IOException is the result.

You cannot use File.ReadAllLines() as-is here, you need to open a FileStream with FileShare.ReadWrite, pass it to a StreamReader and read all lines.

Beware the very troublesome race potential you've got here, there's no guarantee that the last line you'll read is a complete line. Getting only a \r and not the \n at the end of the line is a particularly tricky issue. This will strike randomly and infrequently, the hardest bugs to troubleshoot. Maybe your Flush() call fixes it, I've never been brave enough to put this to the test.

这篇关于尝试从正在写入的文件读取时,为什么会出现未处理的异常:System.IO.IOException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆