#include-once ;=============================================================================== ; ; Function Name: _fileUnsplit($sPath, $iNumParts, $sOutput = Default) ; Description: Unsplit file previously splited by _fileSplit ; Parameter(s): $sPath = Complete path to THE FIRST part of the splited file ; $iNumParts = The exact number of parts (See Remark) ; $sOutput (optional) = Path of the output file ; If not specified, it will be: 'path_of_the_parts'\'origianl_file_name' ; Requirement(s): Created with AutoIt 3.6.1.0, but should work on older version, cause no special functions used ; Return Value(s): Succes - Returns the number of parts pasted together ; Failure - Returns -1 AND: ; - First part file doesn't exists: @error = 1 ; - Number of parts is invalide: @error = 2 ; - Error opening/creating the output file: @error = 3 ; - Error opening one of the parts (probably because it's missing or bad $iNumberParts value): ; @error = 4 AND @extended = number of the part ; Remark: About the $iNumParts parameter: If you specify a smaller number than the number of parts, your file will be corrupt ; If you specify a bigger number than the number of parts, the function will return an error, but your file will be OK! ; Author(s): Matwachich ; ;=============================================================================== ; Func _fileUnsplit($sPath, $iNumParts, $sOutput = Default) Local $sPartsFolder, $var, $sGeneriquePart, $sEntirePart1Name, $sOutFileName, $sOutputPath, $hOutFile, $hF $sPath = _PathFull($sPath) If Not FileExists($sPath) Then ; check if the first part exists Return SetError(1, 0, -1) EndIf If Not IsNumber($iNumParts) Then ; check if number of parts is a number Return SetError(2, 0, -1) EndIf $sPartsFolder = StringTrimRight(StringLeft($sPath, StringInStr($sPath, "\", 1, -1)), 1) ; retreive the folder where the parts are located $var = StringSplit(StringTrimLeft($sPath, StringInStr($sPath, "\", 1, -1)), "_part", 3) ; retreive a generique part file name (without the number of the part) $sGeneriquePart = $var[0] & "_part" ; If $sOutput = Default Then $sEntirePart1Name = StringTrimLeft($sPath, StringInStr($sPath, "\", 1, -1)) ; retreive the entire part1 file name $var = StringSplit($sEntirePart1Name, "_part", 3) ; Retreive the original file name from the parts name $sOutFileName = $var[0] ; $sOutputPath = $sPartsFolder & "\" & $sOutFileName ; sets the output path: 'path_of_the_parts'\'origianl_file_name' Else $sOutputPath = $sOutput ; set the output path: the one specified in the $sOutput parameter EndIf $hOutFile = FileOpen($sOutputPath, 18) ; opens the output file If Not $hOutFile Then ; check Return SetError(3, 0, -1) EndIf For $i = 1 To $iNumParts ; pasting the parts one by one in the output file $hF = FileOpen($sPartsFolder & "\" & $sGeneriquePart & $i, 16) ; opens the current part ($i) If Not $hF Then ; check Return SetError(4, $i, -1) EndIf FileWrite($hOutFile, FileRead($hF)) ; write the content of the part in the output file FileClose($hF) Next FileClose($hOutFile) ; close the output file Return SetError(0, 0, $iNumParts) EndFunc ;=============================================================================== ; ; Function Name: _fileSplit($sPath, $iPartSize, $sDestination = Default) ; Description:: Splits a file into multiple parts of defined size ; Parameter(s): $sPath = Complete path of the file to split ; $iPartSize = Size of a part (in bytes) ; $sDestination = destination folder (where the parts of the file will be created) ; will be created ; (Default = $sPath & "\" & file_name.ext_split & "\" & $file_name.ext & "_part" & $num_of_the_part) ; $iBat = True/False: create a bat file that will assemble the parts (assemble_'file_name'.bat) ; Requirement(s): Created with AutoIt 3.6.1.0, but should work on older version, cause no special functions used ; Return Value(s): Succes - Returns the number of parts created ; Failure - Returns -1 AND: ; - File doesn't exists: @error = 1 ; - Part size is not a number: @error = 2 ; - Enable to create the destination directory: @error = 3 ; - Error opening the file: @error = 4 ; - Error opening one of the parts: @error = 5 AND @extended = the number of the part ; - Error creating/opening the bat file: @error = 6 ; Author(s): Matwachich ; ;=============================================================================== ; _fileSplit("bateau.flv", 1024*1024*2, Default, True) Func _fileSplit($sPath, $iPartSize, $sDestination = Default, $iBat = False) Local $i, $iSize, $iNumParts, $hF, $hNewF, $bRead, $sFileName, $sBatFile = "copy /b " $sPath = _PathFull($sPath) If Not FileExists($sPath) Then ; Check if the input file exists Return SetError(1, 0, -1) EndIf If Not IsNumber($iPartSize) Then ; Check if part's size is valide Return SetError(2, 0, -1) EndIf $iSize = FileGetSize($sPath) ; Get file size $iNumParts = Ceiling($iSize/$iPartSize) ; Get number of parts $sFileName = StringTrimLeft($sPath, StringInStr($sPath, "\", 1, -1)) ; Get the input file name If $sDestination = Default Then ; If destiantion folder is not specified, then it will be: 'path_of_the_file'\'name_of_the_file' & '_split' $sDestination = StringTrimRight($sPath, StringLen($sFileName)) & "\" & $sFileName & "_split" EndIf If Not DirCreate($sDestination) Then ; creats the destination directory Return SetError(3, 0, -1) EndIf $hF = FileOpen($sPath, 16) ; open the file (read mode) If Not $hF Then Return SetError(4, 0, -1) EndIf For $i = 1 To $iNumParts $bRead = FileRead($hF, $iPartSize) ; reads '$iPartSize byte' from the file $hNewF = FileOpen($sDestination & "\" & $sFileName & "_part" & $i, 18) ; open/create a part If Not $hNewF Then FileDelete($sDestination & "\assemble_" & $sFileName & ".bat") ; delete assembler bat Return SetError(5, $i, -1) EndIf $sBatFile &= '"' & $sFileName & "_part" & $i & '"+' FileWrite($hNewF, $bRead) ; write in the part FileClose($hNewF) Next FileClose($hF) If $iBat Then ; Creating the assembler bat $sBatFile = StringTrimRight($sBatFile, 1) $sBatFile &= " " & '"' & $sFileName & '"' $hF = FileOpen($sDestination & "\assemble_" & $sFileName & ".bat", 2) if not $hF then return SetError(6, 0, -1) FileWrite($hF, $sBatFile) FileClose($hF) EndIf Return SetError(0, 0, $iNumParts) EndFunc ; ###################### INTERNAL USE (_pathFull() From File.au3 standard UDF) ###################### ; #FUNCTION# ==================================================================================================================== ; Name...........: _PathFull ; Description ...: Creates a path based on the relative path you provide. The newly created absolute path is returned ; Syntax.........: _PathFull($sRelativePath) ; Parameters ....: $sRelativePath - The relative path to be created ; Return values .: Success - Returns the newly created absolute path. ; Author ........: Valik (Original function and modification to rewrite), tittoproject (Rewrite) ; Modified.......: ; Remarks .......: ; Related .......: _PathMake, _PathSplit, .DirCreate, .FileChangeDir ; Link ..........: ; Example .......: Yes ; Notes .........: UNC paths are supported. ; Pass "\" to get the root drive of $sBasePath. ; Pass "" or "." to return $sBasePath. ; A relative path will be built relative to $sBasePath. To bypass this behavior, use an absolute path. ; =============================================================================================================================== Func _PathFull($sRelativePath, $sBasePath = @WorkingDir) If Not $sRelativePath Or $sRelativePath = "." Then Return $sBasePath ; Normalize slash direction. Local $sFullPath = StringReplace($sRelativePath, "/", "\") ; Holds the full path (later, minus the root) Local Const $sFullPathConst = $sFullPath ; Holds a constant version of the full path. Local $sPath ; Holds the root drive/server Local $bRootOnly = StringLeft($sFullPath, 1) = "\" And StringMid($sFullPath, 2, 1) <> "\" ; Check for UNC paths or local drives. We run this twice at most. The ; first time, we check if the relative path is absolute. If it's not, then ; we use the base path which should be absolute. For $i = 1 To 2 $sPath = StringLeft($sFullPath, 2) If $sPath = "\\" Then $sFullPath = StringTrimLeft($sFullPath, 2) Local $nServerLen = StringInStr($sFullPath, "\") -1 $sPath = "\\" & StringLeft($sFullPath, $nServerLen) $sFullPath = StringTrimLeft($sFullPath, $nServerLen) ExitLoop ElseIf StringRight($sPath, 1) = ":" Then $sFullPath = StringTrimLeft($sFullPath, 2) ExitLoop Else $sFullPath = $sBasePath & "\" & $sFullPath EndIf Next ; If this happens, we've found a funky path and don't know what to do ; except for get out as fast as possible. We've also screwed up our ; variables so we definitely need to quit. If $i = 3 Then Return "" ; A path with a drive but no slash (e.g. C:Path\To\File) has the following ; behavior. If the relative drive is the same as the $BasePath drive then ; insert the base path. If the drives differ then just insert a leading ; slash to make the path valid. If StringLeft($sFullPath, 1) <> "\" Then If StringLeft($sFullPathConst, 2) = StringLeft($sBasePath, 2) Then $sFullPath = $sBasePath & "\" & $sFullPath Else $sFullPath = "\" & $sFullPath EndIf EndIf ; Build an array of the path parts we want to use. Local $aTemp = StringSplit($sFullPath, "\") Local $aPathParts[$aTemp[0]], $j = 0 For $i = 2 To $aTemp[0] If $aTemp[$i] = ".." Then If $j Then $j -= 1 ElseIf Not ($aTemp[$i] = "" And $i <> $aTemp[0]) And $aTemp[$i] <> "." Then $aPathParts[$j] = $aTemp[$i] $j += 1 EndIf Next ; Here we re-build the path from the parts above. We skip the ; loop if we are only returning the root. $sFullPath = $sPath If Not $bRootOnly Then For $i = 0 To $j - 1 $sFullPath &= "\" & $aPathParts[$i] Next Else $sFullPath &= $sFullPathConst ; If we detect more relative parts, remove them by calling ourself recursively. If StringInStr($sFullPath, "..") Then $sFullPath = _PathFull($sFullPath) EndIf ; Clean up the path. While StringInStr($sFullPath, ".\") $sFullPath = StringReplace($sFullPath, ".\", "\") WEnd Return $sFullPath EndFunc ;==>_PathFull