Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我在尝试读取要写入的文件时遇到未处理的异常:System.IO.IOException?_C#_File_Filesystemwatcher - Fatal编程技术网

C# 为什么我在尝试读取要写入的文件时遇到未处理的异常:System.IO.IOException?

C# 为什么我在尝试读取要写入的文件时遇到未处理的异常:System.IO.IOException?,c#,file,filesystemwatcher,C#,File,Filesystemwatcher,我有两个C#应用程序,一个是逐行读取文件(文件a),然后将其内容写入另一个文件(文件B) 第二个应用程序使用FileSystemWatcher for File B查看文件何时更新,并报告程序启动时与文件更改时的行号差异 这就是我现在所要做的,最终我想读取文件上次读取和当前读取之间的行,但直到我可以得到保留的行差 应用程序1的代码是 static void Main(string[] args) { String line; Stream

我有两个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:进程无法访问该文件,因为它正被另一个进程使用”

我有两个用于读写访问的filestreams设置,一个用于FileAccess.Write,另一个用于FileAccess.Read

有什么线索可以解释为什么我会得到这个异常

谢谢 Hew.

提供了两种不获得独占持有权的方法:

FileStream对象将不具有 当您需要时,请独家握住手柄 SafeFileHandle属性为 访问以公开句柄或 FileStream对象被赋予 在其 构造器

文件表明,反过来是正确的:

在不设置SafeFileHandle的情况下打开文件流意味着 FileStream对文件句柄(即 与应该引发的IO异常内联)

input.txt可能无法读取

在第一个应用程序中也使用
using
语句而不是Close()(以防引发异常)

否则就可以了。但是,文件共享可能需要额外的权限(实际上不会影响这一点)

我遗漏了一段代码:

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

流读取器
一起使用。

在这种情况下,允许对文件进行第二次程序读写访问将起作用

//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++;
            }
        }
lines=File.ReadAllLines(args[1]+“\Chat.log”).Length

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

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

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


注意你在这里遇到的非常麻烦的比赛潜力,不能保证你将读到的最后一行是完整的。在行尾仅获取一个\r而不是\n是一个特别棘手的问题。这将随机且不频繁地攻击,这是最难排除的bug。可能是你的Flush()调用修复了它,我从来没有勇气对此进行测试。

哪个应用程序出现了错误?FileShare.ReadWrite负责同时打开文件,但这是否也有助于允许同时访问?@apoorv020:是的,即使对于其他进程也是如此。但它可能需要额外的权限。@spinon抱歉,引发异常的应用程序是FileSystemWatcher应用程序(应用程序2)。安全句柄通常通过网络套接字操作或文件映射公开(应用程序中不使用公开文件句柄的代码)。文件在哪里暗示了这一点?报价中暗示了这一点。反过来说,如果既没有访问SafeFileHandle属性来公开句柄,也没有在其构造函数中为fileStream对象提供SafeFileHandle属性,则fileStream对象将对其句柄具有独占性保留。简单的句子演算:句子A:FS将不具有独占性保留。句子B:使用SafeFileHandle。您使用了
(B=>A)
(~B=>~A)
,这是不等价的
(B=>A)
(~A=>~B)
是等价的。原来的一句话相当于:如果使用了SafeFileHandle,FS将不具有独占性。因此,等价的反向含义是:(不使用SafeFileHandle)当(FS具有独占持有)时,这与:(如果FS具有独占持有),(不使用SafeFileHandle)等价。这意味着你答案中的句子不正确!底线-文本允许FS即使在不使用SafeHandle的情况下也不具有独占性保留。感谢使用“using”的提示,我将应用程序更改为这样做。权限应该可以,因为我可以打开input.txt。我正在以对系统的完全访问权限运行。对于
input.txt
,我的意思是如果没有共享,其他进程无法打开它。+1令人印象深刻。我看到了一些类似的东西,但无法用语言表达。其他答案中已经有了。至于阅读,你是对的。他可以使用一个命名的互斥来轻松解决这个问题。此外,他并不真正阅读这些行(如其内容),只是对它们进行计数。谢谢你,汉斯,我尝试使用Streamreader,它确实起了作用,但我认为阅读每一行来计算要比较的总行数是低效的。我打算这样做,因为我一直在研究如何删除SafeFileHandles,但这似乎不是一个选项。非常感谢。它与File.ReadAllLines()一样有效。没有办法提高效率,只有一种方法可以在引擎盖下读取文本文件。无论如何,文件数据应该从文件系统缓存中出来。+1正是OP所需要的。而不是
args[1]+“\\Chat.log”
他将使用
path
s
//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++;
            }
        }