By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,627 Members | 1,870 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,627 IT Pros & Developers. It's quick & easy.

How do I Wait for files to finish populating a directory before processing...

P: 2
I am using the FilesystemWatcher to look for files in a Directory, it does not matter what the file is. After a file appears it starts my ftp process and I end up with a bunch of 0 byte files because it processed before all the files arrived. I would like to WaitFor... (Files_Created) to finish but dont seem to have the right syntax to get this to work properly. I have working code up until it loops. As you can see I have tried various processes to get it to work... mostly commented out. I also have imported just about everything trying to get this to work. Please ask away. Thanks

Expand|Select|Wrap|Line Numbers
  1. Imports System
  2. Imports System.IO.File
  3. Imports System.IO
  4. Imports System.Threading
  5. Imports System.Collections
  6. Imports System.Collections.Specialized
  7. Imports System.Diagnostics
  8.  
  9. Public Class FileSystemMonitor
  10.  
  11.     Public Shared Sub Main()
  12.         Dim fsw As New FileSystemWatcher()  ' create an object of FileSystemWatcher
  13.  
  14.         ' set properties of FileSystemWatcher object
  15.         fsw.Path = "c:\Test"
  16.         fsw.IncludeSubdirectories = True
  17.  
  18.         ' add event handlers 
  19.         AddHandler fsw.Created, New FileSystemEventHandler(AddressOf File_Created)
  20.  
  21.         fsw.EnableRaisingEvents = True  ' enable monitoring
  22.  
  23.         Console.WriteLine("Started Monitoring WinServ Dir. Press enter key to stop.")
  24.         Console.ReadLine()
  25.  
  26.     End Sub
  27.  
  28.     ' event handler to handle created event 
  29.     Public Shared Sub File_Created(ByVal obj As Object, ByVal e As FileSystemEventArgs)
  30.  
  31.         Dim fName As String = System.IO.Path.GetFileName(e.FullPath) 'file name with extension
  32.         Dim newPath As String = "C:\Test" 'Newpath with no file
  33.         Dim nPathAndFile As String = String.Concat(newPath, fName) 'Newpath with file and ext
  34.         Dim S As New StringCollection()
  35.         Dim T() As String = {nPathAndFile}
  36.         Dim i As String
  37.         Dim Count As Integer = 0
  38.  
  39.         For Each i In T
  40.             Count += 1
  41.             Dim di = New DirectoryInfo(newPath)
  42.             Dim fi = di.GetFiles("*", SearchOption.AllDirectories)
  43.             Console.WriteLine(fi.Length.ToString) ' & " " & nPathAndFile)
  44.  
  45.         Next
  46.  
  47.  
  48.  
  49.  
  50.         'If File.Exists(nPathAndFile) Then
  51.         'Console.WriteLine("Starting Transfer")
  52.         'Dim psi As New System.Diagnostics.ProcessStartInfo("C:\ftp2.bat")
  53.         'psi.RedirectStandardOutput = True
  54.         'psi.WindowStyle = ProcessWindowStyle.Hidden
  55.         'psi.UseShellExecute = False
  56.         'Dim ftp As System.Diagnostics.Process
  57.         'ftp = System.Diagnostics.Process.Start(psi)
  58.         'Dim myOutput As System.IO.StreamReader = ftp.StandardOutput
  59.         'Console.WriteLine(myOutput)
  60.         'ftp.WaitForExit(1000)
  61.         'If ftp.HasExited Then
  62.         'Console.WriteLine("Transfer Done")
  63.         'Dim s As String
  64.         'For Each s In System.IO.Directory.GetFiles("C:\Test")
  65.         'System.IO.File.Delete(s)
  66.         'Next s
  67.         'End If
  68.         'For Each i In T
  69.         'Delete(i)
  70.         'Thread.Sleep(2000)
  71.         'Next
  72.         'End If
  73.     End Sub
  74. End Class
  75. 'Dim delt As New System.Diagnostics.ProcessStartInfo("C:\delt.bat")
  76. 'delt.RedirectStandardOutput = True
  77. 'delt.WindowStyle = ProcessWindowStyle.Hidden
  78. 'delt.UseShellExecute = False
  79. 'Dim delt2 As System.Diagnostics.Process
  80. 'delt2 = System.Diagnostics.Process.Start(delt)
May 26 '10 #1
Share this Question
Share on Google+
3 Replies


tlhintoq
Expert 2.5K+
P: 3,525
Welcome to pain in the butt that is Windows. As soon as a new record is put into the file directory, windows fires a NewFileEvent. Just checking to see if the file exists won't cut it, because even at 0k it does technically exist.

When using FileSystemWatcher I usually put the path of the new file into a Queue rather than react immediately. I can then handle the queue at me leisure; checking every 10 seconds to see if the file size has changed. Once the size has remained stable for 30 seconds I figure it must be done.

Hopefully someone will pop up with a better approach and we can both learn something. But it has been a method that serves me well for a long time.
May 26 '10 #2

P: 2
WOW, that sounds like a tricky process. You wouldnt happen to have any sample code laying around would you?

The problem lies in FSW processing files in a batch but then wants to loop throuth the code for every file. I want it to sit and wait until there is no folder activity (Change or created events) happening before it goes to the ftp. I am not a VB expert and dont know mutch about multi-threading
May 26 '10 #3

tlhintoq
Expert 2.5K+
P: 3,525
It's really not that tricky. Your queue can be an actual 'queue' object.
http://msdn.microsoft.com/en-us/library/7977ey2c.aspx
Or just a simple List<string> of the paths.
Or make a class that has a path, size and date in it to give yourself some flexibility - then make a List<> of those to loop through.

On a timer check the FileInfo.ModifiedDate of each file in the list (or the last known filesize). If it hasn't changed in 30 seconds, you're probably good.

I code in C#, plus it's all proprietary to the company I work for... so I can't really just give it out.

But give it a play. You'll learn more by doing and experimenting anyway.
May 26 '10 #4

Post your reply

Sign in to post your reply or Sign up for a free account.