未处理的异常:System.IO.IOException:进程无法访问文件

Unhandled Exception: System.IO.IOException: The process cannot access the file

我不知道如何解决这个错误。

更新

解决了 LogFile\FWLog.txt 文件已经存在的错误,但是当 LogFile\FWLot.txt 不存在时错误仍然存​​在。

Unhandled Exception: System.IO.IOException: The process cannot access the file 'C:\Users\user\OneDrive\CodeWorkspace\NET\fw\fw\LogFile\FWLog.txt' because it is being used by another process.

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.File.InternalReadAllBytes(String path, Boolean checkHost)
at FW.CreateLog(String logName, String path, DateTime time)
at FW.Watch(String path) at FW.Run()
at FW.Main()

代码:

using System;
using System.IO;

public class FW
{
    private static StreamWriter log;
    public static void Main()
    {
        Run();
    }

    private static void Run()
    {
        string option = "";
        Console.WriteLine("File System Watcher\nThis program monitors activity in a specified directory.");
        string[] args = Environment.GetCommandLineArgs();
        if (args.Length >= 2)
        {
            String path = args[1];
            Watch(path);
        }
        while (!option.Equals("3"))
        {
            do
            {
                Console.Write("Choose an option:\n[1] Monitor a direcotry.\n[2] Open log history\n[3] Quit\n>> ");
                option = Console.ReadLine();
            } while (!option.Equals("1") && !option.Equals("2") && !option.Equals("3"));
            switch (option)
            {
                case "1":
                    Watch("");
                    break;
                case "2":
                    if ((Directory.Exists("LogFile") && !File.Exists("LogFile\FWLog.txt")) || !Directory.Exists("LogFile"))
                    {
                        Console.WriteLine("There are no saved logs.");
                    }
                    else
                    {
                        Console.WriteLine("\nLog History");
                        DumpLog("LogFile\FWLog.txt");
                    }
                    break;
            }
        }
        Console.WriteLine("Quiting...");
    }

    //[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    private static void Watch(string path)
    {
        DateTime time = DateTime.Now;
        string logName = "LogFile\FWLog.txt";
        while (!Directory.Exists(path))
        {
            Console.Write("Please enter a valid absolute directory path (i.e. C:\Users\john\Documents)\n>> ");
            path = Console.ReadLine();
        }
        Console.WriteLine("Monitoring: " + path);
        CreateLog(logName, path, time);
        log = File.AppendText(logName);
        // Create a new FileSystemWatcher and set its properties.
        using (FileSystemWatcher watcher = new FileSystemWatcher())
        {
            watcher.IncludeSubdirectories = true;
            watcher.Path = path;

            // Watch for changes in LastAccess and LastWrite times, and
            // the renaming of files or directories.
            watcher.NotifyFilter = NotifyFilters.LastWrite
                                 | NotifyFilters.FileName
                                 | NotifyFilters.DirectoryName;

            // Add event handlers.
            watcher.Changed += OnChanged;
            watcher.Created += OnChanged;
            watcher.Deleted += OnChanged;
            watcher.Renamed += OnRenamed;

            // Begin watching.
            watcher.EnableRaisingEvents = true;

            // Wait for the user to quit the program.
            Console.WriteLine("Press 'q' to stop monitoring.");
            while (!(Console.ReadLine()).Equals("q")) ;
        }
        log.Close();
    }
    // Define the event handlers.
    private static void OnChanged(object source, FileSystemEventArgs e)
    {
        string status = $"{Path.GetFileName(e.FullPath)} in {Path.GetDirectoryName(e.FullPath)} {e.ChangeType} {DateTime.Now}";
        // Specify what is done when a file is changed, created, or deleted.
        if ((e.FullPath).Contains("LogFile\FWLog.txt"))
        {
            return;
        }
        else
        {
            Console.WriteLine(status);
            log.WriteLine(status);
        }
    }

    private static void OnRenamed(object source, RenamedEventArgs e)
    {
        string status = $"{Path.GetFileName(e.OldFullPath)} Renamed to {Path.GetFileName(e.FullPath)} in {Path.GetDirectoryName(e.FullPath)} {DateTime.Now}";
        // Specify what is done when a file is renamed.
        Console.WriteLine(status);
        log.WriteLine(status);
    }

    private static void CreateLog(string logName, string path, DateTime time)
    {
        if (!Directory.Exists("LogFile"))
            Directory.CreateDirectory("LogFile");
        if (!File.Exists(logName))
            File.Create(logName);
        using (StreamWriter logCreate = File.AppendText(logName))
        {
            if (File.ReadAllBytes(logName).Length == 0)
            {
                logCreate.WriteLine($"Monitored: {path} {time}");
            }
            else
            {
                logCreate.WriteLine($"\nMonitored: {path} {time}");
            }
            logCreate.Close();
        }
    }

    private static void DumpLog(string logFile)
    {
        string line;
        if (File.ReadAllBytes(logFile).Length == 0)
        {
            Console.WriteLine("Log file is empty.");
        }
        else
        {
            using (StreamReader r = File.OpenText(logFile))
            {
                while ((line = r.ReadLine()) != null)
                {
                    Console.WriteLine(line);
                }
                Console.WriteLine();
            }
        }
    }
}

在方法 CreateLog 中,您正在尝试使用 File.ReadAllBytes 读取文件。但是,这个文件在读操作之前已经被File.AppendText打开了,所以才会出现异常。可以在写操作前检查文件是否为空,避免出现这种异常。

部分方法CreateLog请参考以下代码。

            bool isFileEmpty = File.ReadAllBytes(logName).Length == 0;
            using (StreamWriter logCreate = File.AppendText(logName))
            {
                if (isFileEmpty)
                {
                    logCreate.WriteLine($"Monitored: {path} {time}");
                }
                else
                {
                    logCreate.WriteLine($"\nMonitored: {path} {time}");
                }
            }