Yesterday I blogged about a simple class to parse file names, and that inspired me to improve it and add some functionality, which will actually come in handy for a project at work shortly.
The class is pretty self-explanatory, there is really nothing complicated in the code.
When the class is initialized, if a path to a directory (i.e. ending with \) is passed to the constructor the directory is created if it does not exist. If the directory exist, there are functions to copy or move both single files or all files in the directory. Directories can also be deleted using the RemoveDir method.
In addition, there are properties to get the path, file name, extension and file size (in bytes) of the file (if the class was initialized with a file name).
Here is an agent with some examples of how to call the class:
Option Public
Option Declare
Use "Class.FileFunctions"
Sub Initialize
Dim file As FileObject
Dim cnt As Integer
Dim success As Boolean
'*** Create new file object
Set file = New FileObject("D:\Downloads\Downloads\MERP\Assassins of Dol Amroth.pdf")
'*** Copy the file to another (new) directory
Call file.CopyTo("D:\Downloads\MERP1\", file.FileName)
'*** Move the file to a new location and replace space with + in file name
Call file.MoveTo("D:\Downloads\MERP2\", Replace(file.FileName," ","+"))
'*** Create a new directory if it does not exist
Set file = New FileObject("D:\Downloads\MERP3\Test\")
'*** Copy all files in specified directory to another directory
Set file = New FileObject("D:\Downloads\Downloads\MERP\")
cnt = file.CopyAllTo("D:\Downloads\MERP\Backup\")
MsgBox "Copied " & cnt & " files."
'*** Move all files in the previously specified directory to another location
cnt = file.MoveAllTo("D:\Downloads\Middle-Earth Role Playing Game\")
MsgBox "Moved " & cnt & " files."
'*** Remove D:\Downloads\Downloads\MERP\
Call file.RemoveDir("")
'*** Remove D:\Downloads\MERP3\ and Test directory that we created earlier
success = file.RemoveDir("D:\Downloads\MERP3\Test\")
If success = True Then
success = file.RemoveDir("D:\Downloads\MERP3\")
If success = False Then
MsgBox "Failed to delete D:\Downloads\MERP3\"
End If
Else
MsgBox "Failed to delete D:\Downloads\MERP3\Test\"
End If
End Sub
Below is the class itself, I put it in a script library called Class.FileFunctions.
%REM
Copyright (c) Karl-Henry Martinsson 2012.
Some code copyright Andre Guirard (see below).
You are free to use and modify my code, as long as you keep
all copyright info intact. If you improve the code, please
consider sharing it back to the community.
%END REM
Option Public
Option Declare
Type FileDetails
path As String
filename As String
extension As String
filesize As Long
End Type
Class FileObject
Private file As FileDetails
Public silent As Boolean
Public Sub New(filepathname As String)
silent = False
FullPathName = filepathname
If file.FileName = "" Then
If file.Path <> "" Then
On Error 76 GoTo parentDoesNotExist
'No filename but path, then we create that directory (if missing)
If Dir$(file.Path,16)="" Then
createDirectory:
Call MakeDir(file.Path)
End If
End If
file.FileSize = 0
Else
file.FileSize = FileLen(filepathname)
End If
Exit Sub
parentDoesNotExist:
Resume createDirectory
End Sub
Public Property Set FileName As String
file.FileName = FileName
file.Extension = StrRightBack(FileName,".")
End Property
Public Property Get FileName As String
FileName = file.FileName
End Property
Public Property Get Extension As String
Extension = file.Extension
End Property
Public Property Set Extension As String
file.Extension = Extension
End Property
Public Property Set FilePath As String
file.Path = FilePath
If Right(file.Path,1)<>"\" Then
file.Path = file.Path & "\"
End If
End Property
Public Property Get FilePath As String
FilePath = file.Path
End Property
Public Property Set FullPathName As String
Me.FilePath = StrLeftBack(FullPathName,"\")
Me.FileName = StrRightBack(FullPathName,"\")
End Property
Public Property Get FullPathName As String
FullPathName = file.Path & file.FileName
End Property
Public Function CopyTo(ByVal newpath As String, ByVal newname As String) As Boolean
'*** Check if both arguments are blank, then exit
If FullTrim(newpath) = "" Then
If FullTrim(newpath) = "" Then
CopyTo = False
Exit Function
End If
End If
If FullTrim(newpath) = "" Then
newpath = file.Path
End If
If FullTrim(newname) = "" Then
newname = file.FileName
End If
Call MakeDir(newpath)
On Error GoTo errHandlerCopyTo
FileCopy me.FullPathName, newpath + newname
If silent = False Then
Print "Copied " & filename & " from " & file.Path & " to " & newpath
End If
CopyTo = True
exitFunctionCopyTo:
Exit Function
errHandlerCopyTo:
CopyTo = False
Resume exitFunctionCopyTo
End Function
Public Function MoveTo(ByVal newpath As String, ByVal newname As String) As Boolean
'*** Check if both arguments are blank, then exit
If FullTrim(newpath) = "" Then
If FullTrim(newpath) = "" Then
MoveTo = False
Exit Function
End If
End If
If FullTrim(newpath) = "" Then
newpath = file.Path
End If
If FullTrim(newname) = "" Then
newname = file.FileName
End If
Call MakeDir(newpath)
On Error GoTo errHandlerMoveTo
FileCopy me.FullPathName, newpath + newname
Kill me.FullPathName
If silent = False Then
Print "Moved " & filename & " from " & file.Path & " to " & newpath
End If
MoveTo = True
exitFunctionMoveTo:
Exit Function
errHandlerMoveTo:
MoveTo = False
Resume exitFunctionMoveTo
End Function
Public Function CopyAllTo(ByVal newpath As String) As Integer
Dim filename As String
Dim filecount As Integer
'*** Check if both arguments are blank, then exit
If FullTrim(newpath) = "" Then
If FullTrim(newpath) = "" Then
CopyAllTo = 0
Exit Function
End If
End If
If FullTrim(newpath) = "" Then
newpath = file.Path
End If
Call MakeDir(newpath)
On Error GoTo errHandlerCopyAllTo
filename = Dir$(file.Path,2) ' Include hidden files
Do until filename=""
FileCopy file.Path + filename, newpath + filename
If silent = False Then
Print "Copying " & filename & " from " & file.Path & " to " & newpath
End If
filecount = filecount + 1
filename = Dir$()
Loop
CopyAllTo = filecount
exitFunctionCopyAllTo:
Print "Copied " & filecount & " files"
Exit Function
errHandlerCopyAllTo:
CopyAllTo = filecount
Resume exitFunctionCopyAllTo
End Function
Public Function MoveAllTo(ByVal newpath As String) As Integer
Dim filename As String
Dim filecount As Integer
Dim deletelist List As String
'*** Check if both arguments are blank, then exit
If FullTrim(newpath) = "" Then
If FullTrim(newpath) = "" Then
MoveAllTo = 0
Exit Function
End If
End If
If FullTrim(newpath) = "" Then
newpath = file.Path
End If
Call MakeDir(newpath)
On Error GoTo errHandlerMoveAllTo
filename = Dir$(file.Path,2) ' Include hidden files
Do Until filename=""
FileCopy file.Path + filename, newpath + filename
If silent = False Then
Print "Moving " & filename & " from " & file.Path & " to " & newpath
End If
deletelist(filename) = file.Path + filename
filecount = filecount + 1
filename = Dir$()
Loop
Print "Cleaning up..."
ForAll f In deletelist
Kill f
End ForAll
MoveAllTo = filecount
exitFunctionMoveAllTo:
Print "Moved " & filecount & " files"
Exit Function
errHandlerMoveAllTo:
MoveAllTo = filecount
Resume exitFunctionMoveAllTo
End Function
Public Function RemoveDir(ByVal dirpath As String) As Boolean
'*** If blank, use the path in object
If FullTrim(dirpath) = "" Then
dirpath = file.path
End If
On Error GoTo errHandlerRemoveDir
RmDir dirpath
RemoveDir = True
exitRemoveDir:
Exit Function
errHandlerRemoveDir:
RemoveDir = False
Resume exitRemoveDir
End Function
' ===== Private Supporting Functions =====
Private Sub MakeDir(Byval strWhere As String)
' *** This code by Andre Guirard @ IBM
' *** http://www-10.lotus.com/ldd/bpmpblog.nsf/dx/recursive-mkdir-vs.-iteration
' *** Using an iterative method instead of recursive due to stack issues (see link above)
On Error 76 Goto parentDoesNotExist
Dim stack$
Const NL = {
}
Do
Mkdir strWhere
On Error Goto 0 ' first success, stop trapping errors; avoid infinite loop.
strWhere = Strleft(stack, NL) ' "pop" a path for next iteration
stack = Mid$(stack, Len(strWhere)+2)
failed:
Loop Until strWhere = ""
Exit Sub
parentDoesNotExist:
' This error code can indicate other problems, but assume missing parent.
' If not, we get a different error (75) later when trying to create the parent.
Dim fpath$, fname$
SplitFilepath strWhere, fpath, fname
If fpath = "" Then Error 76, "Invalid path: '" & strWhere & "'"
stack = strWhere & NL & stack ' "push" onto stack to retry later.
strWhere = fpath ' try a path one step shorter.
Resume failed
End Sub
Private Sub SplitFilePath(Byval fullpath$, dirpath$, filename$)
' *** This subroutine by Andre Guirard @ IBM
' *** http://www-10.lotus.com/ldd/bpmpblog.nsf/dx/recursive-mkdir-vs.-iteration
' *** Called from MakeDir()
Const DELIMS = {/\:}
While Instr(DELIMS, Right$(fullPath, 1)) ' discard final delimiter character...
fullpath = Left$(fullpath, Len(fullpath)-1)
Wend
Dim candidate$, i%
filename = Strtoken(fullpath, Left$(DELIMS, 1), -1)
For i = 2 To Len(DELIMS)
candidate = Strtoken(fullpath, Mid$(DELIMS, i, 1), -1)
If Len(candidate) < Len(filename) Then
filename = candidate
End If
Next
Dim fplen%
fplen = Len(fullpath)-Len(filename)
If fplen > 0 Then fplen = fplen - 1
dirpath = Left$(fullpath, fplen)
End Sub
End Class
Enjoy!
