FileSystemWatcher – 如何pipe输出到文本文件?

我正在使用FileSystemWatcher类。 我正在尝试将输出传输到文本文件。 我已经添加了StreamWriter fileWriter = new StreamWriter("test.txt"); 但没有输出到文件! 我哪里错了?

 class Program { static void Main(string[] args) { string dirPath = "C:\\"; FileSystemWatcher fileWatcher = new FileSystemWatcher(dirPath); fileWatcher.IncludeSubdirectories = true; fileWatcher.Filter = "*.exe"; // fileWatcher.Filter = "C:\\$Recycle.Bin"; // fileWatcher.Changed += new FileSystemEventHandler(FileWatcher_Changed); fileWatcher.Created += new FileSystemEventHandler(FileWatcher_Created); // fileWatcher.Deleted += new FileSystemEventHandler(FileWatcher_Deleted); // fileWatcher.Renamed += new RenamedEventHandler(FileWatcher_Renamed); fileWatcher.EnableRaisingEvents = true; StreamWriter fileWriter = new StreamWriter("test.txt"); Console.ReadKey(); } } 

你需要打电话

 fileWriter.Write(data); 

另外,你应该像这样包装它:

 using(StreamWriter fileWriter = new StreamWriter("test.txt")) { fileWriter.Write(data); fileWriter.Flush(); // maybe not necessary } 

这将写入数据到文件系统,它应该触发你的FileSystemWatcher对象。

编辑 – 就地例子

 class Program { static void Main(string[] args) { string dirPath = "C:\\"; FileSystemWatcher fileWatcher = new FileSystemWatcher(dirPath); fileWatcher.IncludeSubdirectories = true; fileWatcher.Filter = "*.exe"; // fileWatcher.Filter = "C:\\$Recycle.Bin"; // fileWatcher.Changed += new FileSystemEventHandler(FileWatcher_Changed); fileWatcher.Created += new FileSystemEventHandler(FileWatcher_Created); // fileWatcher.Deleted += new FileSystemEventHandler(FileWatcher_Deleted); // fileWatcher.Renamed += new RenamedEventHandler(FileWatcher_Renamed); fileWatcher.EnableRaisingEvents = true; // updated code using(StreamWriter fileWriter = new StreamWriter("test.txt")) { var data = true; fileWriter.Write(data); } Console.ReadKey(); } } 

实际写入输出流的代码需要在FileWatcher_Created事件处理程序中。 只能写出文件是在创建文件时运行的代码中创建的。

这意味着事件处理程序需要访问您创建的StreamWriter ,否则需要打开输出文件本身,写入一个值,然后在事件触发时关闭它。

由于无法将StreamWriter作为参数传递给事件处理程序,因此只能将事件处理程序的访问权限设置为类级变量,而无法通过静态Main方法进行访问。 您可能需要创建一个类来保存FileSystemWatcherStreamWriter ,并且只需从Main方法实例化该类。

但是,等等,还有更多!

如果您正在写入StreamWriter的过程中,并在该时刻创建另一个文件呢? 你不能同时写两个线程写入一个StreamWriter,否则不好的事情是不可避免的。 所以你需要使用某种锁定来保护对StreamWriter的访问。

我只是使用Log4Net ,而不用担心线程安全或任何其他血淋淋的细节。

把它放在你的AssemblyInfo.cs中:

 [assembly: log4net.Config.XmlConfigurator(ConfigFile="Log4Net.config",Watch=true)] 

每个需要记录日志的类都需要一个记录器。 把它放在每个这样的类定义中:

 private static readonly ILog Log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType ) ; 

以上的原因是它通过其包含的类型来标识每个记录器。 您的log4net.config可以通过记录器过滤/路由/配置日志记录,所以通过这种方式,您可以对日志记录进行大量的控制。 你可以说,在一个看起来不合常理的类上拨出日志记录详细信息,同时让应用程序的其他部分只记录错误和致命错误等级。

您可以通过一个ILog方法(如Console.WriteLine()string.Format()来记录消息:

 Log.InfoFormat( "some-format-string" , ... ) ; 

设置你的log4net.config文件,看起来像这样:

 <log4net> <appender name="Console" type="log4net.Appender.ConsoleAppender"> <layout type="log4net.Layout.PatternLayout"> <!-- Pattern to output the caller's file name and line number --> <conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" /> </layout> </appender> <appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> <file value="example.log" /> <appendToFile value="true" /> <maximumFileSize value="100KB" /> <maxSizeRollBackups value="2" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level %thread %logger - %message%newline" /> </layout> </appender> <root> <level value="DEBUG" /> <appender-ref ref="Console" /> <appender-ref ref="RollingFile" /> </root> </log4net> 

你会记录到控制台和一个文件。 Log4Net将处理日志文件翻转和所有icky位。