Determine that PDF has completed writing to disk

Everyone:

Have small VB.net program (2010) that utilizes the "FileSystemWatcher" control.  Control "watches" for the creation of a particular PDF file, it then moves the file to a predetermined location.  PDF's are created by scanning to the "watched" file.  Scans with fewer than about 30 pages are handled correctly.  Larger scans are the problem.

Problem:
I was getting a corrupted PDF in the move to location on larger scans because the code in the "watched" section was writing the file before the very large scans could complete.  To solve that problem, I put a sleep statement to just pause the program to give the system time to fully write the PDF to file.  Solved my scan problem.  Put a sleep time of 60 seconds.

My solution has now created an additional problem of not allowing other processes to work during the 60 seconds.  Critical programs that need to run.

Now for my question:  Within the subroutine that is triggered by the creation of the file, how do I check that a file is "Completely written to disk, and there is no more activity?  How to do this without using a sleep statement?

So far I've attempted to check file size, but not much luck there.

If possible, just a very short snippet of code would be very helpful, or a very detailed explanation as to how to solve my problem.

Thanks in advance!!

Rick Norris
Rick NorrisAsked:
Who is Participating?
 
käµfm³d 👽Connect With a Mentor Commented:
So I was thinking it would be something along these lines:

Imports System.Threading
Imports System.IO

Public Class Form1
    Public Event Test As WaitCallback

    Private Sub FileSystemWatcher1_Created(sender As System.Object, e As System.IO.FileSystemEventArgs) Handles FileSystemWatcher1.Created
        Dim state As New MonitorData() With {.FilePath = e.FullPath, .Callback = AddressOf WhenFileCompleted}

        ThreadPool.QueueUserWorkItem(AddressOf FileCompletionMonitor, state)
    End Sub

    Private Sub WhenFileCompleted(ByVal filepath As String)
        MessageBox.Show(filepath + " completed!")
    End Sub

    Private Sub FileCompletionMonitor(ByVal state As Object)
        Dim parameters As MonitorData = DirectCast(state, MonitorData)

        While True
            Try
                Using handle As FileStream = File.Open(parameters.FilePath, FileMode.Open, FileAccess.Read, FileShare.None)
                    Exit While
                End Using  ' Using makes sure the file is closed if we acquire the lock. Don't want to lock the file for later processing
            Catch ex As Exception
                ' File lock not obtained
                Thread.Sleep(250)
            End Try
        End While

        parameters.Callback.Invoke(parameters.FilePath)
    End Sub
End Class

Public Class MonitorData
    Public Property FilePath As String
    Public Property Callback As Action(Of String)
End Class

Open in new window


In your FSW handler, you spawn off a new thread that will take care of the checking (and sleeping--only if you don't get the lock). Once you acquire the lock, the file *should* be done writing. At that point, you can invoke a callback method that you can pass the completed file's filename to. The callback's target can handle the processing that you wish to occur once the file i completed.
0
 
käµfm³d 👽Commented:
Without knowing the size of the file being sent, there is no way to absolutely know when a file has been completely written. All that remain are hacks, one of which is to try and obtain an exclusive lock on the file. If you get the lock, then the file is not in use; otherwise, you would need to yield control (probably by sleeping) to another thread for a period, and then recheck the lock later.
0
 
Rick NorrisAuthor Commented:
Correct.... No way to know size... Largest file scaned so far is a little over 300 pages.  I can implement your suggestion; however... How can I "sleep" on a "separate" thread so that it will not intfere with another program??? Does that make sense?
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
Rick NorrisAuthor Commented:
kaufmed:

I'm sorry it's taken me so long to get back.  I am a CPA, and it's extremely busy now.  It looks like your comment above will definitely take care of my problem.  I've copied your code (THANK YOU VERY MUCH), and I will try it from home later this evening.

I will get back with you first thing tomorrow.

Thanks again.
Rick Norris
0
 
käµfm³d 👽Commented:
No problem. Take your time.
0
 
Rick NorrisAuthor Commented:
Sorry it took so long to get back to you.  Your help was invaluable.  Your solution was "spot on"!

Rick
0
All Courses

From novice to tech pro — start learning today.