c# - 未处理的异常: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();
}
}
}
}
解决方案
在方法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}");
}
}
推荐阅读
- xpath - 如何找到 Chrome 插件元素的路径?
- jquery - 以编程方式调用 jquery 数据表单元格单击事件
- scala - 从嵌套的 for-comprehensions 处理堆叠的 State 和 IO monads 返回最终结果
- javascript - 使用来自 localStorage 的 jQuery eq() 填充一组文本区域
- sql - 报表中的 DoCmd.OpenReport 和 ORDER BY
- javascript - 如何修复此 for 循环以翻译数字
- tuples - 有条件地将元组写回excel(仅值> 0)
- javascript - 如何使用 converse.js 中的按钮单击事件在全屏和覆盖聊天之间切换
- java - 如何使用 Vitamio 播放加密的视频文件 (.mpg)?
- django - 使用 Django 的 Kendo UI 网格