我正在使用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();
}
}
答案 0 :(得分:3)
实际写入输出流的代码需要位于FileWatcher_Created
事件处理程序中。您只能写出在创建文件时运行的代码中创建的文件。
这意味着事件处理程序需要访问您创建的StreamWriter
,否则它需要打开输出文件本身,写一个值,然后每次事件触发时关闭它。
由于您无法将StreamWriter
作为参数传递给事件处理程序,因此赋予事件处理程序访问权限的唯一方法是使其成为类级变量,这是您无法做到的来自静态Main
方法。您可能必须创建一个类来同时保存FileSystemWatcher
和StreamWriter
,并且只需从Main
方法实例化该类。
但等等,还有更多!
如果您正在写入StreamWriter,并且在该时刻创建了另一个文件,该怎么办?你不能让两个线程同时写入一个StreamWriter,或者Bad Things是不可避免的。因此,您需要使用某种锁定来保护对StreamWriter的访问。
答案 1 :(得分:2)
您需要致电
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();
}
}
答案 2 :(得分:1)
我只使用Log4Net而不用担心线程安全或任何其他血腥细节。
将它放在AssemblyInfo.cs中:
[assembly: log4net.Config.XmlConfigurator(ConfigFile="Log4Net.config",Watch=true)]
每个要记录某事的类都需要一个记录器。把它放在每个这样的类定义中:
private static readonly ILog Log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType ) ;
上述原因是它通过其包含类型识别每个记录器。您的log4net.config可以通过logger过滤/路由/配置日志记录,因此通过这种方式,您可以对日志记录进行大量控制。比方说,你可以在一个看似行为不端的特定类上拨打日志记录详细程度,同时让应用程序的其余部分仅记录错误,例如ERROR和FATAL级别。
您可以通过其中一种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比特。