将条目号附加到FileSystemWatcher输出 [英] appending an entry number to FileSystemWatcher output

查看:87
本文介绍了将条目号附加到FileSystemWatcher输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,

在这里可能会被视为一篇非常精采的文章,我并不是真的很熟练VB或很多程序员,但是我正在边做边学"驱动器上.

Probably going to be seen as an extremely amature post here, I'm not really skilled in VB or much of a programmer but i'm on a "learn by doing" drive.

我正在开发一个应用程序,该应用程序将为用户创建目录,并使用FileSystemWatcher跟踪创建的目录以及这些目录的更改.

I'm developing an application which creates directories for a user, and tracks the directories created and the changes to these directories using FileSystemWatcher.

到目前为止,我有这个小片段(为回答您对Jimi的评论,已进行了更新):

I've got this little snippet so far (Updated in answer you your comments Jimi):

Button_Click的私人子项:

Private Sub of Button_Click:

    watchfolder = New System.IO.FileSystemWatcher()
    watchfolder.Path = TodaysScanFolder
    watchfolder.Filter = ""
    watchfolder.IncludeSubdirectories = True

    watchfolder.NotifyFilter = IO.NotifyFilters.DirectoryName
    watchfolder.NotifyFilter = watchfolder.NotifyFilter Or
                       IO.NotifyFilters.FileName
    watchfolder.NotifyFilter = watchfolder.NotifyFilter Or
                       IO.NotifyFilters.Attributes

    AddHandler watchfolder.Created, AddressOf logchange
    AddHandler watchfolder.Deleted, AddressOf logchange

    watchfolder.EnableRaisingEvents = True
    btnStartScan.Enabled = False
    btnStopScan.Enabled = True
End Sub

    Public Sub logchange(ByVal source As Object, ByVal e As _
                        System.IO.FileSystemEventArgs)

    If e.ChangeType = IO.WatcherChangeTypes.Created Then
        txt_folderactivity.Text &= "File " & e.FullPath &
                                 " has been created" & vbCrLf
    End If
    If e.ChangeType = IO.WatcherChangeTypes.Deleted Then
        txt_folderactivity.Text &= "File " & e.FullPath &
                                " has been deleted" & vbCrLf
    End If
End Sub

对于每个其他活动,在此之前,我想将输出附加到txt_folderactivity.Text上.然后是2、3,依此类推.

With each additional activity, I want to append the output to txt_folderactivity.Text with a 1, prior to this. Then 2, 3, so on so forth.

您看到此文本框,更改后将输出写入文本文件,如下所示:

You see this text box, on change writes output to a text file like so:

Private Sub txt_folderactivity_TextChanged(sender As Object, e As EventArgs) Handles txt_folderactivity.TextChanged
    str = txt_folderactivity.Text
    My.Computer.FileSystem.WriteAllText(LogFileLoc, str, True)
End Sub

我希望该文本文件的每一行/条目都以1、2、3等开头.另外,正如我所说的VB初学者一样,看起来有些杂乱无章,但功能正常,并且对业务至关重要.任何有关VB学习资源的良好开端的指针都将非常有帮助.谢谢大家

I would like each line/entry to that text file to begin 1, 2, 3 and so on. Plus, as I said total beginner with VB, seem to have pieced together something which looks a bit messy but is functional and will be business critical, any pointers for a good start on relevant VB learning resources would be very helpful. Thanks All

推荐答案

这是一个从FileSystemWatcher继承的类.
它负责配置,启用和禁用事件引发,并具有基本的日志记录和报告功能.

This is a class that inherits from FileSystemWatcher.
It takes care of the configuration, enables and disables the raising of events and has basic logging and reporting capabilities.

FileSystemWatcher的配置:

Configuration of FileSystemWatcher:

.BeginInit() - .EndInit()
BeginInit()用于防止在FileSystemWatcher设置完成之前引发事件.

.BeginInit() - .EndInit()
BeginInit() is used to prevent the raising of events before the FileSystemWatcher setup is completed.

.SynchronizingObject
Set the SynchronizingObject to a Form component. Since the FileSystemWatcher events are marshalled from the system thread pool, this ensures that the event delegates are called on the same thread where the component is created.
If SynchronizingObject is null, accessing the component may result in an Exception or, worse, in a silent failure.

.InternalBufferSize
The internal buffer is used to store the events register and a file path. A buffer larger that the default (8192 bytes) can prevent a buffer overflow, which compromises the rising of events. Here it's set to 32768 bytes.

.Path
对于网络驱动器/共享,请使用UNC路径.

使用方法:

.Path
For network drives/shares use UNC Paths.

How to use it:

定义引用FileWatcher Class的公共对象:

Define a public object that references the FileWatcher Class:

Public FileWatch As FileWatcher

然后您可以在需要时对其进行初始化:

Then you can initialize it whenever you need it:

FileWatch = New FileWatcher("[Path to watch]", 
                            "*",  'All files
                            "[Path to LogFile]", 
                            Me,   'Synchronizing Object
                            Me.[TextBox control used as monitor])


如果不使用[TextBox control used as monitor],则可以为Nothing.


[TextBox control used as monitor] can be Nothing if none is used.

FileWatcher不会立即开始引发/记录事件. EnableRaisingEvents属性在初始化方法中设置为False.
您可以使用其方法启动和停止它的活动:

The FileWatcher doesn't immediately start to raise/log events; the EnableRaisingEvents property is set to False in the initialization method.
You can start and stop it's activity with its methods:

Me.FileWatch.StartWatcher()
Me.FileWatch.StopWatcher()


启动和停止FileWatcher是已注册(记录)的活动.
List(Of DateTime)用于存储这些事件.请参见FW_EventLogger Class.


Starting and stopping the FileWatcher is a registered (logged) activity.
A List(Of DateTime) is used to store these events. See the FW_EventLogger Class.

其他存储的信息是:

Other stored informations are:

  • 已删除的文件数.
  • 创建的文件数
  • 已注册事件的总数(用于比较).
  • 日志文件的大小.
  • Number of files Deleted.
  • Number of files Created
  • Overall number of registered events (for comparison).
  • Size of the Log File.

ActivityReport()属性返回一个简单的报告:

The ActivityReport() property returns a simple report:

Dictionary(Of String, String) = FileWatcher.ActivityReport()


日志文件如下所示:


This is what the Log File looks like:

00000001 - 2018/02/28 21:00:25 - File D:\Temp\New Text Document.txt has been created
00000002 - 2018/02/28 21:00:29 - File D:\Temp\New Microsoft Access Database.accdb has been created
00000003 - 2018/02/28 21:00:34 - File D:\Temp\New WinZip File.zip has been created
00000004 - 2018/02/28 21:00:44 - File D:\Temp\New Microsoft Access Database.accdb has been deleted
00000005 - 2018/02/28 21:00:44 - File D:\Temp\New Text Document.txt has been deleted
00000006 - 2018/02/28 21:00:44 - File D:\Temp\New WinZip File.zip has been deleted


局限性::如果有要求(将TextBox控件引用传递给类初始化),则用户界面会通过 同步对象.如果UI线程由于某种原因忙碌,则 底层FileSystemWatcher缓冲的事件将堆积.这 可以(并且既然可以)将导致事件的丢失.这是 内部缓冲区设置为默认值的4倍的原因.反正 如果受监视的活动很高,那将永远不够.在正常情况下 条件下,它可以处理10/秒.事件没有问题.除此之外, 使用FIFO队列缓冲区的异步代理方法必须 放置在事件侦听器和数据使用者之间.

Limitatons: If requested (a TextBox control reference is passed to the class initialization), the UI is updated synchronously through a synchronization object. If the UI thread is busy for some reason, the events the underlying FileSystemWatcher is buffering will pile up. This can (and since it can it will) cause the loss of events. This is the reason why the internal buffer is set to 4x the default. Anyway, it won't ever be enough if the monitored activity is high. In normal condition, it can handle 10/sec. events without problem. Beyond that, an asynchronous proxy method that makes use a FIFO queue buffer must be placed between the event listeners and the data consumers.

基于:

Visual Studio 2013, Update 5
.Net Framework 4.7.1

更新至:

Visual Studio 2017, 15.8.4
.Net Framework 4.7.1


Imports System.Collections.Generic
Imports System.IO
Imports System.Windows.Forms


Public Class FileWatcher
    Inherits FileSystemWatcher

    Private EventLogger As FW_EventLogger
    Private Prompt As TextBox = Nothing

    Public Sub New()
        Me.New("", "", "", Nothing, Nothing)
    End Sub

    Public Sub New(fswPath As String, fswFilter As String, logFile As String, SyncObject As Form, SyncPrompt As TextBox)
        Me.Prompt = SyncPrompt
        Me.EventLogger = New FW_EventLogger With {.LogFileName = logFile}

        SetupFileWatcher(fswPath, fswFilter, SyncObject)
    End Sub

    Public Sub StartWatcher()
        Me.EventLogger.TimeStart.Add(DateTime.UtcNow)
        If Me.Prompt IsNot Nothing Then
            Me.Prompt.AppendText(String.Format("Logger Start Time: {0}" +
                                 Environment.NewLine, DateTime.UtcNow.ToString()))
        End If
        Me.EnableRaisingEvents = True
    End Sub

    Public Sub StopWatcher()
        Me.EnableRaisingEvents = False
        Me.EventLogger.TimeStop.Add(DateTime.UtcNow)
        If Me.Prompt IsNot Nothing Then
            Me.Prompt.AppendText(String.Format("Logger Stop Time: {0}" +
                                 Environment.NewLine, DateTime.UtcNow.ToString()))
        End If
    End Sub

    Public ReadOnly Property ActivityReport() As Dictionary(Of String, String)
        Get
            Return Me.CreateActivityReport()
        End Get
    End Property

    Public Property PromptControl As TextBox
        Get
            Return Me.Prompt
        End Get
        Set(value As TextBox)
            Me.Prompt = value
        End Set
    End Property


    Public Sub SetupFileWatcher(fwPath As String, fwFilter As String, SyncObject As Form)
        If fwPath.Length = 0 Then
            Return
        End If

        Me.BeginInit()
        Me.SynchronizingObject = SyncObject
        Me.InternalBufferSize = 32768
        Me.IncludeSubdirectories = True
        Me.Filter = fwFilter
        Me.Path = fwPath
        Me.NotifyFilter = NotifyFilters.FileName Or NotifyFilters.CreationTime
        Me.EnableRaisingEvents = False

        'Set the handler to the events you want to receive
        AddHandler Me.Created, New FileSystemEventHandler(AddressOf Me.OnCreated)
        AddHandler Me.Deleted, New FileSystemEventHandler(AddressOf Me.OnDeleted)
        'The other events, should they become necessary.
        'this.Changed += new FileSystemEventHandler(this.OnChanged);
        'this.Renamed += new RenamedEventHandler(this.OnRenamed);

        Me.EndInit()
    End Sub

    Private Function CreateActivityReport() As Dictionary(Of String, String)
        With Me.EventLogger
            Dim log As New Dictionary(Of String, String)
            log.Add("Created", .FileCreated.ToString())
            log.Add("Deleted", .FileDeleted.ToString())
            log.Add("TotalEvents", .EventsLogged.ToString())
            log.Add("LogFileSize", If(File.Exists(.LogFileName), New FileInfo(.LogFileName).Length.ToString(), "N/A"))
            log.Add("StartTime", If(.TimeStart.Count > 0, .TimeStart.First().ToString(), "Not Started"))
            log.Add("LastStopTime", If(.TimeStop.Count > 0, .TimeStop.Last().ToString(), "Never"))
            log.Add("Status", If(Me.EnableRaisingEvents = True, "Running", "Stopped"))
            Return log
        End With
    End Function

    Protected Overloads Sub OnCreated(sender As Object, e As FileSystemEventArgs)
        Dim Msg As String = "File " & e.FullPath & " has been created"
        Me.EventLogger.Update(Msg, FW_EventLogger.EventType.FileCreated)
        If Me.Prompt IsNot Nothing Then
            Me.Prompt.AppendText(Msg + Environment.NewLine)
            Me.Prompt.ScrollToCaret()
        End If
    End Sub

    Protected Overloads Sub OnDeleted(sender As Object, e As FileSystemEventArgs)
        Dim Msg As String = "File " & e.FullPath & " has been deleted"
        Me.EventLogger.Update(Msg, FW_EventLogger.EventType.FileDeleted)
        If Me.Prompt IsNot Nothing Then
            Me.Prompt.AppendText(Msg + Environment.NewLine)
            Me.Prompt.ScrollToCaret()
        End If
    End Sub

    'The Event Logger Class
    Private Class FW_EventLogger

        Sub New()
            Me.TimeStart = New List(Of DateTime)
            Me.TimeStop = New List(Of DateTime)
        End Sub

        Public Enum EventType As Integer
            FileCreated = 0
            FileDeleted
        End Enum

        Public Property FileDeleted As Integer
        Public Property FileCreated As Integer
        Public Property EventsLogged As Integer
        Public Property TimeStart As List(Of DateTime)
        Public Property TimeStop As List(Of DateTime)
        Public Property LogFileName As String

        Public Sub Update(NewEvent As String, TypeOfEvent As EventType)

            If Me.LogFileName <> String.Empty Then
                If TypeOfEvent = EventType.FileCreated Then Me.FileCreated += 1
                If TypeOfEvent = EventType.FileDeleted Then Me.FileDeleted += 1
                Me.EventsLogged += 1
                Using LogFileWriter As StreamWriter = New StreamWriter(Me.LogFileName, True, Encoding.UTF8)
                    LogFileWriter.WriteLine(Me.EventsLogged.ToString().PadLeft(8, "0"c) +
                                            " - {0} - {1}", DateTime.UtcNow.ToString("yyyy/MM/dd hh:mm:ss"), NewEvent)
                End Using
            End If
        End Sub
    End Class

End Class

这篇关于将条目号附加到FileSystemWatcher输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆