[英]How do you get the name of a new file created using FileSystemWatcher?
[英]FileSystemWatcher fires before file is saved - how do you “pause” the process?
这是我尝试代码的逻辑:
服务监视目录中的.pptx文件。 如果文件已更改,请转换为jpg。 然后执行其他任务,稍后将添加。
我正在使用文件存储对象,但是一旦打开文件即会触发,因此我想通过检查文件是否“锁定”来停止该过程。 我以为“锁定时”循环可以解决问题,但是没有。 下面是简化的代码原型,如果您能看一下它,我想表明我在做错什么,和/或是否有更好的方法为生产环境编写代码。 pptx文件可以打开很长时间。
namespace FileWatcherDemo
{
public class Program
{
static void Main(string[] args)
{
FileSystemWatcher fsWatcher = new FileSystemWatcher();
fsWatcher.Path = @"e:\\";
fsWatcher.NotifyFilter = NotifyFilters.LastWrite;
fsWatcher.Filter = "*.pptx";
fsWatcher.Changed += new FileSystemEventHandler(fsWatcher_Changed);
//fsWatcher.Created += new FileSystemEventHandler(fsWatcher_Changed);
//fsWatcher.Deleted += new FileSystemEventHandler(fsWatcher_Changed);
//fsWatcher.Renamed += new RenamedEventHandler(fsWatcher_Changed);
fsWatcher.EnableRaisingEvents = true;
Console.ReadKey();
}
static void fsWatcher_Changed(object sender, FileSystemEventArgs e)
{
try
{
while( !IsFileLocked())
{
Console.WriteLine("Changed Event Fired");
Microsoft.Office.Interop.PowerPoint.Application app = new Microsoft.Office.Interop.PowerPoint.Application();
Presentation pptPresentation = app.Presentations.Open(@"e:\\HowTo.pptx", MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
pptPresentation.SaveAs(@"e:\\Output", PpSaveAsFileType.ppSaveAsJPG, MsoTriState.msoFalse);
pptPresentation.Close();
}
}
catch (Exception ex)
{
using (StreamWriter w = File.AppendText(@"e:\\ErrorLog.txt"))
{
Log(ex.Message.ToString(), w);
Log(ex.StackTrace.ToString(), w);
w.Close();
}
}
Console.ReadKey();
}
static bool IsFileLocked()
{
FileStream fs = null;
FileInfo file = new FileInfo(@"e:\\HowTo.pptx");
try
{
fs = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if(fs != null)
fs.Close();
}
return false;
}
public static void Log(string LogMessage, TextWriter w)
{
w.Write("\r\nLog Entry: ");
w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
w.WriteLine(" :");
w.WriteLine(" {0}", LogMessage.ToString());
w.WriteLine("------------------------------------------");
w.Flush();
}
}
}
这是另一个想法:当FileSystemWatcher检测到更改(您说它立即触发文件打开)时,记录文件的LastModifiedTime并继续循环直到文件的LastModifiedTime更改(假定LastModifiedTime仅在保存文件时才写入) -我不知道这实际上是什么时候完成的,然后执行转换为JPG的过程。
编辑
添加应该演示如何跟踪文件修改时间的代码:
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(()=> DoTest());
t.Start();
Console.WriteLine("Waiting...");
Console.ReadKey();
}
private static void DoTest()
{
FileSystemWatcher fsw = new FileSystemWatcher("C:\\");
fsw.Filter = "*.txt";
fsw.Changed += new FileSystemEventHandler(fsw_Changed);
fsw.Deleted += new FileSystemEventHandler(fsw_Deleted);
fsw.Renamed += new RenamedEventHandler(fsw_Renamed);
fsw.Created += new FileSystemEventHandler(fsw_Created);
fsw.EnableRaisingEvents = true;
}
static void fsw_Created(object sender, FileSystemEventArgs e)
{
FileInfo fi = new FileInfo(e.FullPath);
Console.WriteLine("File Created: "+e.FullPath);
Console.WriteLine("Creation Time: " + fi.CreationTime.ToLongTimeString());
Console.WriteLine("Last Access Time: " + fi.LastAccessTime.ToLongTimeString());
Console.WriteLine("Last Write Time: " + fi.LastWriteTime.ToLongTimeString());
Console.WriteLine("Length: " + fi.Length);
}
static void fsw_Renamed(object sender, RenamedEventArgs e)
{
FileInfo fi = new FileInfo(e.FullPath);
Console.WriteLine("File Renamed: "+e.FullPath);
Console.WriteLine("Creation Time: " + fi.CreationTime.ToLongTimeString());
Console.WriteLine("Access Time: " + fi.LastAccessTime.ToLongTimeString());
Console.WriteLine("Last Write Time: " + fi.LastWriteTime.ToLongTimeString());
Console.WriteLine("Length: " + fi.Length);
}
static void fsw_Deleted(object sender, FileSystemEventArgs e)
{
FileInfo fi = new FileInfo(e.FullPath);
Console.WriteLine("File Deleted: "+e.FullPath);
Console.WriteLine("Creation Time: " + fi.CreationTime.ToLongTimeString());
Console.WriteLine("Last Access Time: " + fi.LastAccessTime.ToLongTimeString());
Console.WriteLine("Last Write Time: " + fi.LastWriteTime.ToLongTimeString());
}
static void fsw_Changed(object sender, FileSystemEventArgs e)
{
FileInfo fi = new FileInfo(e.FullPath);
Console.WriteLine("File Changed: "+e.FullPath);
Console.WriteLine("Creation Time: " + fi.CreationTime.ToLongTimeString());
Console.WriteLine("Last Access Time: " + fi.LastAccessTime.ToLongTimeString());
Console.WriteLine("Last Write Time: " + fi.LastWriteTime.ToLongTimeString());
Console.WriteLine("Length: " + fi.Length);
}
}
为了使FileSystemWatcher适用于生产级代码,您需要做大量的逻辑工作。
你要保持事件处理程序很轻,只是队列发生什么事,然后再对其进行处理。
使用计时器(最好使用System.Threading)以1000ms的延迟处理队列,当您收到事件时,停止/启动计时器。
检查队列中是否有同一文件的多个事件,例如,程序可以创建一个文件,然后再次将其删除。
编辑:我只是做了一个快速的Google搜索,发现了一篇文章和示例代码,可以使您90%到达那里。
http://csharp-codesamples.com/2009/02/file-system-watcher-and-large-file-volumes/
编辑2:只是重新阅读您的问题。 上面的建议仍然适用,但是您需要做一些其他事情来解决您的问题:
与其他Office应用程序一样,Powerpoint会创建一个带有~
前缀的隐藏临时文件。
检查文件修改时间戳。 当您第一次注意到文件已更改时,请保存修改时间,并在下次文件更改时与它进行比较。
您需要设置文件系统监视程序的一些标志属性来更改修改时间。
希望所有这些对您有帮助...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.