FileSystemWatcher - Как передать вывод в текстовый файл? - PullRequest
2 голосов
/ 20 мая 2011

Я использую класс 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();
    }
}

Ответы [ 3 ]

3 голосов
/ 20 мая 2011

Код, который фактически записывает в выходной поток, должен находиться внутри обработчика события FileWatcher_Created.Вы можете записать только то, что файл был создан в коде, который запускается при его создании.

Это означает, что обработчику событий необходим доступ к созданному вами StreamWriter, иначеоткройте сам выходной файл, запишите значение, а затем закрывайте его каждый раз при возникновении события.

Поскольку вы не можете передать StreamWriter обработчику события в качестве аргумента, единственный способ датьдоступ обработчика событий к нему - сделать его переменной класса, чего нельзя сделать с помощью статического метода Main.Возможно, вам придется создать класс для хранения FileSystemWatcher и StreamWriter, и просто создать экземпляр этого класса из метода Main.

Но подождите, есть еще!

Что, если вы находитесь в процессе записи в StreamWriter, и в этот момент создается другой файл?Вы не можете одновременно записывать два потока в один StreamWriter, иначе плохие вещи неизбежны.Поэтому вам необходимо защитить доступ к StreamWriter с помощью какой-либо блокировки.

2 голосов
/ 20 мая 2011

Вам нужно вызвать

fileWriter.Write(data);

Кроме того, вы должны обернуть его так:

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

Это запишет данные в файловую систему и должно вызвать ваш объект FileSystemWatcher.

edit - пример на месте

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(); 
    }
}
1 голос
/ 21 мая 2011

Я бы просто использовал 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 позаботится о переносе файла журнала и всех неприглядных битах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...