WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Files and Directories

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

udfFileCopyFlat

Keywords:   udfFileCopyFlat 

Sometimes it may be useful to collect files, which are located somewhere in a folder tree, into one flat folder, do some common work on them, and re-distribute them into the folder tree.

There exists the commandline tool XXCOPY.EXE by Kan Yabumoto, which does this task in a speedy and reliable manner.

Here are two WinBatch udf's which work similarly.

- Files buried down in the tree come into view to the user into one folder.
- Re-distribute files into another logical tree structure by playing with the iAlign mode.
- Combined with (partial) renaming, there may be some interesting advantages.
- If the files are to be worked on several times, then it is an advantage to collect them once and work on them together in flat manner in one place. Afterwards they can be re-distributed to their storage location.
- You can use the udf to collect files from different drives and redistribute to one drive ...


;==========================================================================================================================================
; udfFileCopyFlat  (sSourceFolder, sFileMask, sTargetFolder, iAlign, sSubMask)  ; Copy folder tree to flat folder.
; udfFileCopyFlatR (sSourceFolder, sFileMask, sTargetFolder, iAlign)            ; Copy flat folder to folder tree.
;==========================================================================================================================================
; Version 2.0  20030103  Detlev Dalitz
; uses 'File Search Extender' ("wsrch34i.dll").
;==========================================================================================================================================


;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffilecopyflat",IntControl(77,103,0,0,0),@TAB) then goto skip_udffilecopyflat

#DefineFunction udfFileCopyFlat (sSourceFolder, sFileMask, sTargetFolder, iAlign, sSubMask) ; Copy folder tree to flat folder.
If !DirExist(sSourceFolder) Then Return (-1) ; Source Folder does not exist.
sFolderNow = DirGet()
iSourceCount = 0
iTargetCount = 0

AddExtender("wsrch34i.dll")

sSourceFolder = FileNameShort(sSourceFolder)
iHandle = srchInit(sSourceFolder,sFileMask,"","",8+16) ; 8=include hidden files; 16=recurse subfolders
While @TRUE
   sSrchPath = srchNext(iHandle)
   If (sSrchPath == "") Then Break
   If (FileNameShort(FilePath(sSrchPath)) == sSourceFolder)
      GoSub ProcessFile
      Continue
   EndIf
   If (sSubMask == "") Then Break
   sFolder = ItemExtract(Max(2,ItemCount(sSrchPath,"\")-1),sSrchPath,"\")
   If (sFolder > "")
      sFolder = StrLower(sFolder)
      sSubMask = StrLower(sSubMask)
      If !StrIndex(sFolder,".",0,@BACKSCAN) Then sFolder = StrCat(sFolder,".")
      If (StrIndexWild(sFolder,sSubMask,1) == 1) Then GoSub ProcessFile
   EndIf
EndWhile
srchFree(iHandle)

DirChange(sFolderNow)
Return (iSourceCount-iTargetCount)


:ProcessFile
iSourceCount = iSourceCount + 1
sFileLong = FileNameLong(sSrchPath)
sFolderLong = FilePath(sFileLong)

; Build the flattened folder string.
iResult = 0
iLen = 0
Select @TRUE
Case (StrIndexWild(sFolderLong,"?:\",1) == 1) ; DOS drive letter with absolute path "D:\".
   iLen = 3
   Break
Case (StrIndexWild(sFolderLong,"\\?*\?*\",1) == 1) ; UNC "\\SERVER\SHARE\".
   iLen = StrLenWild(sFolderLong,"\\?*\?*\",1)
   Break
EndSelect
sFolderFlat = StrSub(sFolderLong,iLen+1,-1)
iStrLen = StrLen(sFolderFlat)
If (StrSub(sFolderFlat,iStrLen,1) == "\") Then sFolderFlat = StrSub(sFolderFlat,1,iStrLen-1)
sFolderFlat = StrReplace(sFolderFlat,"`",".`")
sFolderFlat = StrReplace(sFolderFlat,"\","`")

; Create target folder.
iStrLen = StrLen(sTargetFolder)
If (StrSub(sTargetFolder,iStrLen,1) == "\") Then sTargetFolder = StrSub(sTargetFolder,1,iStrLen-1)
If !DirExist(sTargetFolder)
   sFolder = ""
   iItemCount = ItemCount(sTargetFolder,"\")
   For iItem=1 to iItemCount
      sFolder = StrCat(sFolder,ItemExtract(iItem,sTargetFolder,"\"),"\")
      If !DirExist(sFolder)
         iLastErrorMode = ErrorMode(@OFF)
         DirMake(sFolder)
         ErrorMode(iLastErrorMode)
      EndIf
   Next
   If !DirExist(sTargetFolder) Then Return (-2) ; Target Folder does not exist.
EndIf

sFile = ItemExtract(-1,sFileLong,"\")
sFileNew = StrReplace(sFile,"`",".`")
Select iAlign
Case -1 ; Left
   sFileNew = StrCat(sFolderFlat,"`",sFileNew)
   Break
Case 1 ; Right
   sFileNew = StrCat(sFileNew,"`",sFolderFlat)
   Break
Case 0 ; Middle
Case iAlign ; Middle
   sFileNew = StrCat(FileRoot(sFileNew),"`",sFolderFlat,".",FileExtension(sFileNew))
   Break
EndSelect
sFileNew = StrCat(sTargetFolder,"\",sFileNew)
FileCopy(sFileLong,sFileNew,0)
iTargetCount = iTargetCount + (FileExist(sFileNew) > 0)

Return ; from GoSub
;..........................................................................................................................................
; This function "udfFileCopyFlat" copies files from a folder tree into one flat folder.
;
; Return values:
;  0 ... Operation may be done successfully.
; -1 ... Source Folder does not exist.
; -2 ... Target Folder does not exist.
; n>0 .. The number of files which have not been copied successfully.
;
; Parameters:
; sSourceFolder ....... Source Folder to start from.
; sFileMask ........... Group of files, e.g. "*.hlp".
; sTargetFolder ....... Destination Folder, e.g. "D:\Temp\FlatFolder\".
; iAlign .............. The position of the source folder path to be inserted into target filename.
; iAlign= -1 .......... Left.
; iAlign= 0 ........... Middle (should be the default use).
; iAlign= 1 ........... Right.
; sSubMask ............ Defines to search in subfolders too.
; sSubMask= "" ........ Only source folder will be used.
; sSubMask= "*.*" ..... Search source folder and all subfolders.
; sSubMask= "TMP*.*" .. Search source folder and in subfolders with foldernames fitting to the mask, e.g. "TMP*.*
;
; Hint:
; This udf makes use of the 'File Search Extender' AddExtender("wsrch34i.dll").
; By default RequestFlag=8 this udf is designed to see hidden files too.
; This makes it obsolete, to code an additional IntControl (5,1,0,0,0) statement before calling this udf.
;
;
; This Function "udfFileCopyFlat" combines the source folder path (Filepath without drive)
; with the source filename to form a long filename which is always unique (and shows where the file is from).
; The source filepath becomes part of the target filename.
;
; Examples:
; 1. The file "D:\Programme\WinBatch\Windows Interface Language.hlp"
; is copied to folder "D:\Flat\" using option iAlign=-1 (source path is combined to the left of the filename):
; "D:\Flat\Programme`WinBatch`Windows Interface Language.hlp"
;
; 2. The file "D:\Programme\WinBatch\Windows Interface Language.hlp"
; is copied to folder "D:\Flat\" using option iAlign=0 (source path is combined into the middle of the filename):
; "D:\Flat\Windows Interface Language`Programme`WinBatch.hlp"
;
; 3. The file "D:\Programme\WinBatch\Windows Interface Language.hlp"
; is copied to folder "D:\Flat\" using option iAlign=1 (source path is combined to the right of the filename):
; "D:\Flat\Windows Interface Language.hlp`Programme`WinBatch"
;
;
; To rebuild the folder tree from "flattened" files simply use the corresponding "udfFileCopyFlatR()" function.
;
; To be always in sync with the original folder tree structure and filenames,
; make sure to use the same iAlign mode in both directions, e.g. flatten and deflatten with iAlign=0.
;
; Be aware of interesting naming effects, if you do interchange the modes on flattening and deflattening.
;
; The idea of 'Flattening' was originally envolved by Kan Yabumoto, mailto:tech@xxcopy.com,
; as one frightening feature of his world's best 'copy and more' command line tool XXCOPY.EXE.
; I heartly say 'Thank You, Kan', especially for your explanations regarding the use of the back-apostrophe "`".
;
; Detlev Dalitz.20030103
;..........................................................................................................................................
#EndFunction

:skip_udffilecopyflat
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
If (ItemLocate("udffilecopyflatr",IntControl(77,103,0,0,0),@TAB)>0) Then Goto skip_udffilecopyflatr

#DefineFunction udfFileCopyFlatR (sSourceFolder, sFileMask, sTargetFolder, iAlign) ; Copy flat folder to folder tree.
If !DirExist(sSourceFolder) Then Return (-1) ; Source Folder does not exist.
sFolderNow = DirGet()
iSourceCount = 0
iTargetCount = 0

AddExtender("wsrch34i.dll")

sTargetFolder = StrCat(sTargetFolder,StrSub("\",1,(StrSub(sTargetFolder,StrLen(sTargetFolder),1)<>"\")))
sSourceFolder = FileNameShort(sSourceFolder)
iHandle = srchInit(sSourceFolder,sFileMask,"","",8) ;  8=include hidden files
While @TRUE
   sSrchPath = srchNext(iHandle)
   If (sSrchPath == "") Then Break
   GoSub ProcessFile
EndWhile
srchFree(iHandle)

DirChange(sFolderNow)
Return (iSourceCount-iTargetCount)


:ProcessFile
iSourceCount = iSourceCount + 1
sFileLong = FileNameLong(sSrchPath)
sFile = ItemExtract(-1,sFileLong,"\")
sFileNew = StrReplace(sFile,".`",@LF) ; Temporary replacement.
sFolderNew = ""

If StrIndex(sFileNew,"`",0,@FWDSCAN)
   Select iAlign
   Case -1 ; Left
      iPosRight  = StrIndex(sFileNew,"`",0,@BACKSCAN)
      sFileNew   = StrReplace(sFileNew,@LF,"`")
      sFolderNew = StrSub(sFileNew,1,iPosRight-1)
      sFileNew   = StrSub(sFileNew,iPosRight+1,-1)
      Break
   Case 1 ; Right
      iPosLeft   = StrIndex(sFileNew,"`",0,@FWDSCAN)
      sFileNew   = StrReplace(sFileNew,@LF,"`")
      sFolderNew = StrSub(sFileNew,iPosLeft+1,-1)
      sFileNew   = StrSub(sFileNew,1,iPosLeft-1)
      Break
   Case 0 ; Middle
   Case iAlign ; Middle
      iPosLeft   = StrIndex(sFileNew,"`",0,@FWDSCAN)
      sFileNew   = StrReplace(sFileNew,@LF,"`")
      sFolderNew = StrSub(FileRoot(sFileNew),iPosLeft+1,-1)
      sFileNew   = StrCat(StrSub(sFileNew,1,iPosLeft-1),".",FileExtension(sFileNew))
      Break
   EndSelect
   sFolderNew = StrReplace(sFolderNew,"`","\")
EndIf
sFolderNew = StrCat(sTargetFolder,sFolderNew)
sFileNew   = ItemInsert(sFileNew,-1,sFolderNew,"\")

If !DirExist(sFolderNew)
   sFolder = ""
   iItemCount = ItemCount(sFolderNew,"\")
   If (StrSub(sFolderNew,StrLen(sFolderNew),1) == "\") Then iItemCount = iItemCount - 1
   For iItem=1 To iItemCount
      sFolder = StrCat(sFolder,ItemExtract(iItem,sFolderNew,"\"),"\")
      If !DirExist(sFolder)
         iLastErrorMode = ErrorMode(@OFF)
         DirMake(sFolder)
         ErrorMode(iLastErrorMode)
      EndIf
   Next
EndIf
If DirExist(sFolderNew) Then FileCopy(sFileLong,sFileNew,0)
iTargetCount = iTargetCount + (FileExist(sFileNew) > 0)

Return ; from GoSub
;..........................................................................................................................................
; This function "udfFileCopyFlatR" copies 'flattened' files from one folder into a tree folder structure.
;
; This function reverses the operation previously done by the function "udfFileCopyFlat".
; See further explanations in description of "udfFileCopyFlat".
;
; Return values:
;  0   ... Operation may be done successfully.
;  n>0 ... The number of files which have not been copied successfully.
;
; Parameter:
; sSourceFolder ... Source Folder containing 'flattened' filenames.
; sFileMask ....... Group of files, e.g. "*.txt"
; sTargetFolder ... Destination Folder, e.g. "D:\NewStructure\"
; iAlign .......... The position of the previously inserted folder path in the 'flattened' filename:
; iAlign = -1 ..... Left
; iAlign = 0 ...... Middle (should be the default use)
; iAlign = 1 ...... Right
;
; Hint:
; This udf makes use of the 'File Search Extender' AddExtender("wsrch34i.dll").
; By default RequestFlag=8 this udf is designed to see hidden files too.
; This makes it obsolete, to code an additional IntControl (5,1,0,0,0) statement before calling this udf.
;
;
; To be always in sync with the original folder tree structure and filenames,
; make sure to use the same iAlign mode in both directions, e.g. flatten and deflatten with iAlign=0.
;
; Be aware of interesting naming effects, if you do interchange the modes on flattening and deflattening.
;
; The idea of 'Flattening' was originally envolved by Kan Yabumoto, mailto:tech@xxcopy.com,
; as one frightening feature of his world's best 'copy and more' command line tool XXCOPY.EXE.
; I heartly say 'Thank You, Kan', especially for your explanations regarding the use of the back-apostrophe "`".
;
; Detlev Dalitz.20030103
;..........................................................................................................................................
#EndFunction

:skip_udffilecopyflatr
;------------------------------------------------------------------------------------------------------------------------------------------



; --- test ---
sFolderNow = DirGet()

sTempFolder = Environment("temp")
sTempFolder = StrCat(sTempFolder,StrSub("\",(StrSub(sTempFolder,StrLen(sTempFolder),1)<>"\"),1))


:test1 ; Folder tree to flat folder.

; Define the base source folder.
; For the test let us start in WinBatch Main folder
DirChange(DirHome()) ; WinBatch system folder
DirChange("..")      ; WinBatch main folder
sFromFolder = DirGet()
;sFromFolder = "\\FSDD1\SYS\TEMP\LONGNAME\"

; Define the Filemask.
; For the test we collect all .hlp files.
sFileMask = "*.hlp"

; Define the flat target folder.
; For the test we create a subfolder in the systems temp folder.
sToFolder = StrCat(sTempFolder, "Flat\")

; Define the flatten alignment. (-1=Left, 0=Middle, 1=Right)
iAlign = 0

; Define SubFolderMask ("" = Don't search; "*.*" = Search all; "WW*.DIR" = Search as specified).
sSubMask = "WW*.*"
;sSubMask = "*.*"
;sSubMask = ""

; Call the 'Flattener'.
iResult = udfFileCopyFlat(sFromFolder,sFileMask,sToFolder,iAlign,sSubMask)

; View the flat folder.
If (iResult == 0) Then Run("explorer",StrCat("/e, /root, ",sToFolder))



:test2 ; Flat folder to folder tree (Rebuild tree).

; We use all flat files from the test flat folder.
sFromFolder = StrCat(sTempFolder, "Flat\")

; Define the Filemask.
; For the test we collect all files.
sFileMask = "*.*"

; For the test we create a subfolder in the system temp folder.
sToFolder = StrCat(sTempFolder, "FlatR\")

; Define the flatten alignment. (-1=Left, 0=Middle, 1=Right)
iAlign = 0

; Call the 'FlatRebuilder'.
iResult = udfFileCopyFlatR(sFromFolder,sFileMask,sToFolder,iAlign)

; View folder tree.
If (iResult == 0) Then Run("explorer",StrCat("/e, /root, ",sToFolder))


DirChange(sFolderNow)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
*EOF*



Article ID:   W15755
File Created: 2003:05:13:11:29:56
Last Updated: 2003:05:13:11:29:56