簡體   English   中英

為什么我在嘗試從正在寫入的文件中讀取時遇到未處理的異常:System.IO.IOException?

[英]Why am I getting a Unhandled Exception: System.IO.IOException when trying to read from a file being written to?

我有兩個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設置了另一個。

關於為什么我會得到這個例外的任何線索?

謝謝嘿。

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++;
            }
        }

MSDN提供了兩種不獲得獨占保留的方法:

當訪問SafeFileHandle屬性以暴露句柄或FileStream對象在其構造函數中被賦予SafeFileHandle屬性時,FileStream對象將不會對其句柄進行獨占保持。

文檔暗示反之亦然:

在不設置SafeFileHandle的情況下打開FileStream意味着FileStream在文件句柄上保持獨占保留(它與應該拋出的IO異常內聯)。

StreamReader sr = new StreamReader("f:\\watch\\input.txt");

input.txt可能無法讀取?

在第一個應用程序中也使用using語句而不是Close()(如果拋出異常)。

否則就可以了。 文件共享可能需要額外的權限(不能真正影響它)。

我錯過了一段代碼:

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

streamStreamReader一起使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM