首页 > 解决方案 > 未处理的异常:System.IO.IOException:进程无法访问文件

问题描述

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

更新

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

未处理的异常:System.IO.IOException:进程无法访问文件“C:\Users\user\OneDrive\CodeWorkspace\NET\fw\fw\LogFile\FWLog.txt”,因为它正被另一个进程使用。

在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
在 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();
            }
        }
    }
}

标签: c#ioexceptionfilesystemwatcher

解决方案


在方法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}");
                }
            }

推荐阅读