AdvancedHMI Software
General Category => Open Discussion => Topic started by: bachphi on June 09, 2017, 12:07:26 PM
-
Using FileSystemWatcher, one can monitor a folder for file creation, next making sure file upload complete before processing the file.
Public Function FileUploadCompleted(filename As String) As Boolean
' If the file can be opened for exclusive access it means that the file
' is no longer locked by another process.
Try
Using inputStream As FileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.None)
Return True
End Using
Catch generatedExceptionName As IOException
Return False
End Try
End Function
using a While loop, one can check for File Upload complete, but sleep time is not an efficient way, would you have a more efficient way to do this:
While Not FileUploadCompleted(e.FullPath)
System.Threading.Thread.Sleep(500)
End While
-
Does the FileSystemWatcher fire multiple events such as when the file is first created, then subsequent times when it is changed as data is added to it? I am wondering if trying to open the file in the file changed event will fail multiple times until the file lock is released which would mean the upload is complete.
-
The watcher only watch for created event and not changed, deleted, renamed. Currently, it does not use any NotifyFilter, I think it could have used NotifyFilter.LastWrite
-
Here is something along the lines that I was thinking, but not sure if it will actually work:
Private FirstCreatedFile As String
Private Sub FileSystemWatcher1_Created(sender As Object, e As IO.FileSystemEventArgs) Handles FileSystemWatcher1.Created
Console.WriteLine(Now & " File created " & e.FullPath)
If String.IsNullOrEmpty(FirstCreatedFile) Then FirstCreatedFile = e.FullPath
End Sub
Private Sub FileSystemWatcher1_Changed(sender As Object, e As IO.FileSystemEventArgs) Handles FileSystemWatcher1.Changed
Console.WriteLine(e.FullPath & " has changed")
If e.FullPath = FirstCreatedFile Then
Console.WriteLine(Now & " Changed")
Try
Using sr As New System.IO.StreamReader(e.FullPath)
Console.WriteLine(Now & " Ready")
End Using
Catch ex As Exception
Console.WriteLine(Now & " Not Ready. " & ex.Message)
End Try
End If
End Sub
-
That might works! more logical than using sleep time for sure. Thanks Archie.
-
This is what I ended up with:
Imports System.IO
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim fsw As New System.IO.FileSystemWatcher
fsw.Path = Application.StartupPath
fsw.Path = fsw.Path.Substring(0, fsw.Path.LastIndexOf("\")) + "\XferedData"
fsw.NotifyFilter = (NotifyFilters.LastWrite Or NotifyFilters.FileName)
fsw.Filter = "*.txt"
AddHandler fsw.Changed, New FileSystemEventHandler(AddressOf OnChanged)
AddHandler fsw.Created, New FileSystemEventHandler(AddressOf OnChanged)
fsw.EnableRaisingEvents = True
End Sub
Private Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs)
Dim wct As WatcherChangeTypes = e.ChangeType
Debug.WriteLine("File : {0} {1}", e.FullPath, wct.ToString())
Try
Using inputStream As FileStream = File.Open(e.FullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
Debug.WriteLine(Now & " READY ")
End Using
Catch ex As IOException
Debug.WriteLine(Now & " NOT READY YETT " & ex.Message)
End Try
End Sub
End Class