我有一个监视目录的控制台应用程序,它只运行一次,我需要应用程序继续运行并查看文件目录。
代码还检查文件是否已经存在,如果是,那么它会移动它,没有它应该等待和观察,但等待和观察没有发生。
这是代码
class Program
{
public static String stagepath = @"C:\Users\a\Desktop\.NET Data Loader\stage\";
public static String archivePath = @"C:\Users\a\Desktop\.NET Data Loader\archive\";
static void Main(string[] args)
{
DirectoryInfo dirinfo = new DirectoryInfo(stagepath);
FileInfo[] file = dirinfo.GetFiles();
if (file.Length > 0)
{
MoveFile(stagepath);
}
else
{
MonitorDirectory(stagepath);
}
}
public static void MonitorDirectory(string path)
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = path;
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Changed += FileCreated;
watcher.EnableRaisingEvents = true;
}
private static void FileCreated(object sender, FileSystemEventArgs e)
{
if (!FileIsReady(stagepath+e.Name)) return;
System.Threading.Thread.Sleep(1000);
MoveFile(stagepath);
}
private static bool FileIsReady(string path)
{
try
{
using (var file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
{
return true;
}
}
catch (IOException)
{
return false;
}
}
private static void MoveFile(string path)
{
string[] fileNames = Directory.GetFiles(path);
var sort = from fn in fileNames
orderby new FileInfo(fn).Name ascending
orderby new FileInfo(fn).LastWriteTime ascending
select new FileInfo(fn).Name;
foreach (string fi in sort)
{
System.IO.File.Move(stagepath +fi, archivePath+fi);
Console.WriteLine($"File {fi} has been sucessfully moved ");
}
}
}
答案 0 :(得分:1)
放置将文件移动到循环中的代码,例如while循环。确保在每个循环后放置一个Thread.Sleep。 MSDN - Thread.Sleep
初始化时,只需将FileSystemWatcher的事件连接一次。
可能会想要一种退出循环的方法,除非杀死进程就足够了。
<强>更新强>
我对它进行了修改,因此不需要循环。您将不得不对其进行一些修改以获得您想要的结果,但至少现在您有一个有效的例子。在将来使用Visual Studio / IDE调试器时,原始示例中存在许多错误。
您的问题特别是您的文件路径将路径和文件名一起阻塞,例如位于C:\ temp \ foo.txt的文件将变为C:\ tempfoo.txt。然后你检查文件是否可以在移动之前打开,但由于格式错误的路径不存在而无法打开。此外,控制台只需要保持打开状态,不需要循环。只是移动文件的代码有错误,事件仍然被正确触发。您可能希望从FileCreatedInMonitoredDirectory事件处理程序中删除睡眠,我认为不需要它,但我将其保留在那里,因为它是最初的原因。
using System;
using System.IO;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
private static string _monitoringPath = @"C:\temp";
private static string _destinationPath = @"C:\dest";
static void Main(string[] args)
{
MonitorDirectory(_monitoringPath);
Console.ReadKey();
}
public static void MonitorDirectory(string path)
{
var watcher = new FileSystemWatcher();
watcher.Path = path;
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Changed += FileCreatedInMonitoredDirectory;
watcher.EnableRaisingEvents = true;
}
private static void FileCreatedInMonitoredDirectory(object sender, FileSystemEventArgs e)
{
MoveFilesInDirectory(_monitoringPath);
System.Threading.Thread.Sleep(1000);
}
private static bool CanFileBeOpened(string path)
{
try
{
using (var file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))
return true;
}
catch (IOException ioEx)
{
Console.WriteLine($"Warning: File could not be opened, it will not be moved. {ioEx}" );
return false;
}
}
private static void MoveFilesInDirectory(string dirPath)
{
string[] fileNames = Directory.GetFiles(dirPath);
var sortedFileNames = from fn in fileNames
orderby new FileInfo(fn).Name ascending
orderby new FileInfo(fn).LastWriteTime ascending
select new FileInfo(fn).Name;
foreach (string fileName in sortedFileNames)
{
string filePath = Path.Combine(_monitoringPath, fileName);
if (!CanFileBeOpened(filePath))
continue;
var fileInfo = new FileInfo(filePath);
if (fileInfo.Length > 0)
{
File.Move(Path.Combine(_monitoringPath, fileName), Path.Combine(_destinationPath, fileName));
Console.WriteLine($"File {fileName} has been moved successfully.");
}
}
}
}
}
答案 1 :(得分:0)
您只需更改以下代码:
static void Main(string[] args)
{
DirectoryInfo dirinfo = new DirectoryInfo(stagepath);
FileInfo[] file = dirinfo.GetFiles();
if (file.Length > 0)
{
MoveFile(stagepath);
}
else
{
MonitorDirectory(stagepath);
}
Console.ReadKey();
}
当您使用文件观察程序时,另一个线程会在您运行应用程序之前保持活动状态。所以你需要让你的应用程序运行任何策略。