Learn VisualBasic.NET with Me: file mirroring, lost data

I'm bummed out, because a tutorial about events, delegates, and multithreading that I wrote got lost. There was some database problem on the server, and the text didn't get saved. It just compiled information from the last blog entires, but, it was pretty good. Oh well, I must forge on with this little project.

The latest really good news is that the threading stuff is working. I also added a little time-checking feature so that the batch processor will work for a while in the evening, take a break while backups happen, and then work again in the early morning.

File visitor

Someone else is batch processing with vb: Processing files within a file structure with plug-ins and events

File mirror

This is a class that helps you copy a file, mirroring the directory structure at the destination. You set it up, and copy files over.

It's suitable for situations where you aren't cloning the entire file tree, but only selected files. For example, it's appropriate for this little project because we don't want to copy all the files across, just the ones linked from the main files we're copying. Analyzing the main file gives us a list of additional files to copy.

For other situations, where entire directory trees are to be copied, there are more efficient algorithms (like a depth-first recursive function).

There's a Perl version too.

Imports System.Text
Imports System.IO
' Encapsulates file copying across directories, when you need to
' reproduce the directory tree at the destination.  Useful when copying
' more than one file.
'
' dim fm as filemirror = new filemirror( "G:\", "Q:\" )
' fm.copy("G:\123\345\a.txt")
' fm.move("G:\123\345\b.txt")
Class FileMirror
    Public sourceRootDir As String
    Public destRootDir As String
    Public Sub New(ByVal srd As String, ByVal drd As String)
        sourceRootDir = srd
        destRootDir = drd
    End Sub
    ' fm.Copy( "C:\source\root\dir\and\path\to\file.ext" )
    ' Copies file.ext, setting the destination to the path by replacing
    ' the source root dir with the destination root dir.
    Public Sub Copy(ByVal pth As String)
        Dim dest As String = Me.DestFromSource(pth)
        Dim d As String = Path.GetDirectoryName(dest)
        If d <> String.Empty Then
            Directory.CreateDirectory(d)
        End If
        File.Copy(pth, dest)
    End Sub
    ' Slightly paranoid deleter only deletes if there's a copy at the mirror.
    Public Sub DeleteOriginal(ByVal pth As String)
        Dim dest As String = Me.DestFromSource(pth)
        If File.Exists(dest) And File.Exists(pth) Then
            Dim original As FileInfo = New FileInfo(pth)
            Dim clone As FileInfo = New FileInfo(dest)
            If original.Length = clone.Length Then
                File.Delete(pth)
            End If
        End If
    End Sub
    Public Sub Move(ByVal pth As String)
        Me.Copy(pth)
        Me.DeleteOriginal(pth)
    End Sub
    Private Function DestFromSource(ByVal pth As String) As String
        Dim sb As StringBuilder = New StringBuilder(pth)
        If (pth.StartsWith(sourceRootDir)) Then
            sb.Replace(sourceRootDir, destRootDir)
        Else
            ' throw exception
        End If
        DestFromSource = sb.ToString
    End Function
End Class

Tomorrow or Sunday, I'll probably hack a class that makes OLE safer. This class will set up the application to trap OLE timeouts, and try to kill the offending program. That way, the job can continue even if the server croaks or chokes on a bad file. Incidentally, the inability to do this via VBA within Excel was the reason why the project transitioned to VB.NET