1

Тема: VBScript & CMD: разделение файла на фрагменты и их последующее слияние

По мотивам темы LangMF 7.7:Разбиение файла на фрагменты.

Я решил попробовать, насколько возможно проделать аналогичную операцию, заменив использование LangMF функционалом ADODB.Stream. Практическое применение данный скрипт в настоящее время вряд ли будет иметь, но демонстрирует ещё один пример работы с бинарными данными посредством ADODB.Stream.

Замечания:
* скрипт предназначен для исполнения под хостом cscript.exe;
* Microsoft в статье LoadFromFile Method в ADO 2.8 SDK пишет:

Because 2 bytes may be added to the beginning of the stream for encoding, the size of the stream may not exactly match the size of the file from which it was loaded.

Надеюсь, что эти байты, даже если и появляются, то также исчезают при записи потока методом SaveToFile.

Split.vbs

Option Explicit

Const adTypeBinary = 1
Const adTypeText   = 2

Const adModeRead      = 1
Const adModeWrite     = 2
Const adModeReadWrite = 3

Const adSaveCreateNotExist  = 1
Const adSaveCreateOverWrite = 2


Dim objNamedArgs
Dim objWshShell
Dim objFSO
Dim objTS
Dim objStreamSource
Dim objStreamDest

Dim strSourceFile
Dim strDestFolder
Dim lngPartSize
Dim boolNoAskReWrite
Dim boolCreateCMD

Dim intPartNumber
Dim boolDone


Set objNamedArgs    = WScript.Arguments.Named
Set objWshShell     = WScript.CreateObject("WScript.Shell")
Set objFSO          = WScript.CreateObject("Scripting.FileSystemObject")
Set objStreamSource = WScript.CreateObject("ADODB.Stream")
Set objStreamDest   = WScript.CreateObject("ADODB.Stream")


If objNamedArgs.Exists("Help") Or objNamedArgs.Exists("?") Then
    ShowUsage
    QuitInfo "", 0, 0
End If

If objNamedArgs.Exists("SourceFile") Then
    strSourceFile = objNamedArgs.Item("SourceFile")
    
    If Not objFSO.FileExists(strSourceFile) Then
        QuitInfo "Исходный файл " & strSourceFile & " не найден", 2, 0
    End If
Else
    ShowUsage
    QuitInfo "Не указан обязательный параметр /SourceFile", 1, 0
End If

If objNamedArgs.Exists("DestFolder") Then
    strDestFolder = objNamedArgs.Item("DestFolder")
Else
    strDestFolder = objWshShell.CurrentDirectory
End If

If objNamedArgs.Exists("PartSize") Then
    lngPartSize = Clng(objNamedArgs.Item("PartSize"))
Else
    lngPartSize = 1457664
End If

If objNamedArgs.Exists("Y") Then
    boolNoAskReWrite = True
Else
    boolNoAskReWrite = False
End If

If objNamedArgs.Exists("Cmd") Then
    boolCreateCMD = True
Else
    boolCreateCMD = False
End If

With WScript.StdOut
    .WriteLine ""
    .WriteLine "Разделение файла на части"
    .WriteLine ""
    .WriteLine "Исходный файл                            : " & strSourceFile
    .WriteLine "Папка назначения для набора              : " & strDestFolder
    .WriteLine "Размер отдельной части набора            : " & FormatNumber(lngPartSize, 0) & " байт"
    .WriteLine "Перезаписывать существующие части набора : " & IIf(boolNoAskReWrite, "Да", "Спросить")
    .WriteLine "Создавать командный файл для слияния     : " & IIf(boolCreateCMD, "Да", "Нет")
    .WriteLine ""
End With

intPartNumber = 1
boolDone = False

With objStreamDest
    .Mode = adModeReadWrite
    .Type = adTypeBinary
    
    .Open
End With

With objStreamSource
    .Mode = adModeReadWrite
    .Type = adTypeBinary
    
    .Open
    
    .LoadFromFile strSourceFile
    
    Do
        WritePart objStreamSource
        
        intPartNumber = intPartNumber + 1
    Loop Until .EOS Or boolDone
    
    .Close
End With

With objStreamDest
    .Close
End With

If boolCreateCMD And Not boolDone Then
    Set objTS = objFSO.CreateTextFile(objfso.BuildPath(strDestFolder, "Join.cmd"), True, False)
    
    objTS.Write CmdText()
    objTS.Close
    
    Set objTS = Nothing
End If

Set objStreamDest   = Nothing
Set objStreamSource = Nothing
Set objFSO          = Nothing
Set objWshShell     = Nothing
Set objNamedArgs    = Nothing

WScript.Quit 0
'=============================================================================

'=============================================================================
Sub WritePart(ByRef objStream)
    Dim strPartNumber
    Dim strDestPartFile
    
    strPartNumber = Right("0000" & CStr(intPartNumber), Len("0000"))
    strDestPartFile = objFSO.BuildPath(strDestFolder, _
        objFSO.GetFileName(strSourceFile) & ".part" & strPartNumber & ".bin")
    
    WScript.StdOut.WriteLine "Обрабатывается часть #" & strPartNumber & ": " & strDestPartFile
    
    With objStreamDest
        .Write objStream.Read(lngPartSize)
        
        If objFSO.FileExists(strDestPartFile) Then
            If boolNoAskReWrite Then
                .SaveToFile strDestPartFile, adSaveCreateOverWrite
            Else
                If MsgBox("Файл " & strDestPartFile & " существует. Перезаписать?", _
                    vbOKCancel + vbQuestion + vbDefaultButton2) = vbOK Then
                    
                    .SaveToFile strDestPartFile, adSaveCreateOverWrite
                Else
                    WScript.StdErr.WriteLine "Обработка была прервана по желанию пользователя"
                    boolDone = True
                End If
            End If
        Else
            .SaveToFile strDestPartFile, adSaveCreateNotExist
        End If
        
        .Position = 0
        .SetEOS
    End With
End Sub
'=============================================================================

'=============================================================================
Sub QuitInfo(strInfo, intErrorlevel, intPause)
    With WScript
        If Len(strInfo) <> 0 Then
            If intErrorlevel = 0 Then
                .StdOut.WriteLine strInfo
            Else
                .StdErr.WriteLine strInfo
            End If
        End If
        
        If intPause <> 0 Then
            .Sleep intPause * 1000
        End If
        
        .Quit intErrorlevel
    End With
End Sub
'=============================================================================

'=============================================================================
Sub ShowUsage()
    WScript.StdOut.WriteLine _
        "Использование:" & vbCrLf & _
        "    " & WScript.ScriptName & " /Help | /?" & vbCrLf & _
        "    " & WScript.ScriptName & " /SourceFile:<FileName> [/DestFolder:<Path>] [/PartSize:<Size>] [/Y] [/Cmd]" & vbCrLf & _
        "" & vbCrLf & _
        "Описание     :" & vbCrLf & _
        "    Скрипт " & WScript.ScriptName & " позволяет разделить файл на несколько частей" & vbCrLf & _
        "    (в данной версии скрипта — не более 9999 частей) заданного размера." & vbCrLf & _
        "    Эти части в последующем можно слить в исходный файл с помощью команды" & vbCrLf & _
        "    copy или пакетного файла, создание которого можно задать при разделении." & vbCrLf & _
        "" & vbCrLf & _
        "Параметры    :" & vbCrLf & _
        "/Help или /? : Эта справка." & vbCrLf & _
        "" & vbCrLf & _
        "/SourceFile  : Имя исходного файла для разбиения на части." & vbCrLf & _
        "    Файлы отдельных частей получат имена вида <name.ext.part###.bin>, где:" & vbCrLf & _
        "        name.ext — имя.расширение исходного файла;" & vbCrLf & _
        "        ###      — номер отдельной части исходного файла." & vbCrLf & _
        "    Впоследствии они могут быть склеены в исходный файл <name.ext> командой" & vbCrLf & _
        "        copy /b name.ext.part001.bin+...+name.ext.partNNN.bin name.ext" & vbCrLf & _
        "    См. также параметр /Cmd ниже." & vbCrLf & _
        "" & vbCrLf & _
        "/DestFolder  : Папка, куда будут помещены отдельные части исходного файла." & vbCrLf & _
        "    Если не указана, будет использована текущая папка." & vbCrLf & _
        "" & vbCrLf & _
        "/PartSize    : Размер отдельной части." & vbCrLf & _
        "    Если не указан, подразумевается размер стандартной 3.5"" дискеты" & vbCrLf & _
        "    — 1.44 Мб (1457664 байт)." & vbCrLf & _
        "" & vbCrLf & _
        "/Y           : Перезаписывать существующие файлы набора без подтверждения." & vbCrLf & _
        "    Если параметр /Y не указан, будет выдан запрос на перезапись" & vbCrLf & _
        "    существующего файла." & vbCrLf & _
        "" & vbCrLf & _
        "/Cmd         : Создать пакетный файл для слияния отдельных частей." & vbCrLf & _
        "    В той же папке, куда будут помещены отдельные части файла, будет создан" & vbCrLf & _
        "    пакетный файл Join.cmd. Чтобы воссоздать исходный файл из набора" & vbCrLf & _
        "    отдельных частей, запустите пакетный файл Join.cmd, задав ему" & vbCrLf & _
        "    в качестве параметра имя файла первой части (*.part0001.bin) набора." & vbCrLf & _
        "    Если параметр /Cmd не указан, пакетный файл не создаётся." & vbCrLf & _
        "" & vbCrLf & _
        "Примеры      :" & vbCrLf & _
        "    " & WScript.ScriptName & " /SourceFile:""c:\My Downloads\K-Lite Codec Pack\klcodec400f.exe""" & vbCrLf & _
        "    " & WScript.ScriptName & " /SourceFile:""c:\xpcd\i386\driver.cab"" /PartSize:5000000" & vbCrLf & _
        "    " & WScript.ScriptName & " /SourceFile:driver.cab /DestFolder:""c:\temp"" /Y /Cmd" & vbCrLf & _
        ""
End Sub
'=============================================================================

'=============================================================================
Function CmdText()
    Dim i
    Dim arrStrings
    
    CmdText = _
        "@echo off                                                                     " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "setlocal enableextensions enabledelayedexpansion                              " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "if [%1]==[] (                                                                 " & vbCrLf & _
        "    call :Using %~nx0                                                          " & vbCrLf & _
        "    exit /b 1                                                                  " & vbCrLf & _
        ")                                                                             " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "set tsf=%~1                                                                   " & vbCrLf & _
        "set sf=%tsf:.part0001.bin=%                                                   " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "if [""%tsf%""]==[""%sf%""] (                                                  " & vbCrLf & _
        "    call :NotFirstPart %tsf% %~nx0                                             " & vbCrLf & _
        "    exit /b 2                                                                  " & vbCrLf & _
        ")                                                                             " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "if not exist ""%tsf%"" (                                                      " & vbCrLf & _
        "    call :NotExistFirstPart %tsf%                                              " & vbCrLf & _
        "    exit /b 3                                                                  " & vbCrLf & _
        ")                                                                             " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "echo.                                                                         " & vbCrLf & _
        "echo Восстановление исходного файла %sf% из частей                            " & vbCrLf & _
        "echo.                                                                         " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "copy /y nul ""%sf%"" > nul                                                    " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "for /l %%i in (1,1,9999) do (                                                 " & vbCrLf & _
        "    set number=0000%%i                                                         " & vbCrLf & _
        "    set pf=%sf%.part!number:~-4!.bin                                           " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "    if exist ""!pf!"" (                                                        " & vbCrLf & _
        "        echo Слияние !pf!...                                                   " & vbCrLf & _
        "        copy /b /y ""%sf%""+""!pf!"" ""%sf%"" > nul                            " & vbCrLf & _
        "    ) else (                                                                   " & vbCrLf & _
        "        echo.                                                                  " & vbCrLf & _
        "        echo Процесс слияния завершён                                          " & vbCrLf & _
        "        goto :eof                                                              " & vbCrLf & _
        "    )                                                                          " & vbCrLf & _
        ")                                                                             " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "endlocal                                                                      " & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "exit /b 0                                                                     " & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        ":Using                                                                        " & vbCrLf & _
        "    echo.                                                                      " & vbCrLf & _
        "    echo Использование:  %1 ^<имя файла первой части набора^>                  " & vbCrLf & _
        "    echo.                                                                      " & vbCrLf & _
        "    echo Пример       :  %1 driver.cab.part0001.bin                            " & vbCrLf & _
        "    echo.                                                                      " & vbCrLf & _
        "    echo     При отсутствии хотя бы одной из отдельных частей набора           " & vbCrLf & _
        "    echo     обработка завершается, и полученный слитый файл не будет          " & vbCrLf & _
        "    echo     совпадать с исходным.                                             " & vbCrLf & _
        "    goto :eof                                                                  " & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        ":NotFirstPart                                                                 " & vbCrLf & _
        "    echo.                                                                      " & vbCrLf & _
        "    echo Файл %1 не является первой частью набора                              " & vbCrLf & _
        "    echo.                                                                      " & vbCrLf & _
        "    call :Using %2                                                             " & vbCrLf & _
        "    goto :eof                                                                  " & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        "                                                                              " & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        ":NotExistFirstPart                                                            " & vbCrLf & _
        "    echo.                                                                      " & vbCrLf & _
        "    echo Файл %1 не найден                                                     " & vbCrLf & _
        "    echo.                                                                      " & vbCrLf & _
        "    goto :eof                                                                  " & vbCrLf & _
        "::============================================================================" & vbCrLf
        
    arrStrings = Split(CmdText, vbCrLf)
    
    For i = LBound(arrStrings) To UBound(arrStrings)
        arrStrings(i) = RTrim(arrStrings(i))
    Next
    
    CmdText = StrConvert(Join(arrStrings, vbCrLf), "cp866", "Windows-1251")
End Function
'=============================================================================

'=============================================================================
Function StrConvert(strText, strSourceCharset, strDestCharset)
    Const adTypeText = 2
    Const adModeReadWrite = 3
    
    Dim objStream
        
    Set objStream = WScript.CreateObject("ADODB.Stream")
    
    With objStream
        .Type = adTypeText
        .Mode = adModeReadWrite
        
        .Open
        .Charset = strSourceCharset
        .WriteText strText
        .Position = 0
        .Charset = strDestCharset
        strConvert = .ReadText
    End With
    
    Set objStream = Nothing
End Function
'=============================================================================

'=============================================================================
Function IIf(strIF, strThen, strElse)
    If Eval(strIF) Then
        If UCase(TypeName(strThen)) = "STRING" Then
            IIf = strThen
        Else
            IIf = Eval(strThen)
        End If
    Else
        If UCase(TypeName(strElse)) = "STRING" Then
            IIf = strElse
        Else
            IIf = Eval(strElse)
        End If
    End If
End Function
'=============================================================================

Время сборки исходного файла из полученных отдельных частей с помощью сгенерированного пакетного файла, из-за особенностей работы команды copy и неоптимальности применённого алгоритма, растёт в геометрической прогрессии с размером исходного файла и количеством отдельных частей и может занимать очень значительное время:

The gray Cardinal пишет:

Файл размером 732 439 773 был разбит [скриптом — alexii] на 3663 части примерно за 10 минут.
Сборка - сильно дольше, начал тормозить где-то на 1200-м файле, через полтора часа я вырубил (собралось чуть меньше, чем наполовину), Celeron(R) D CPU 3.06GHz, 500 Мб ОЗУ, WinXP SP3.

2

Re: VBScript & CMD: разделение файла на фрагменты и их последующее слияние

Вторая версия скрипта родилась в результате размышления над изначальным вариантом подобного же скрипта AutoIt коллеги Diamond'а.

Изменения:
* запрос «MsgBox» заменён на чтение консоли «WScript.StdIn.ReadLine()» (даже не знаю, зачем я его «впихнул» в первый вариант);
* как следствие предыдущего, на вопрос о перезаписи теперь можно отвечать «A» — «All» (Все).
* временный каталог для слияния частей набора создаётся в текущем каталоге;
* список файлов для слияния стал храниться в самом пакетном файле «Join.cmd», так что теперь не нужно «…указывать параметром пакетного файла первую часть набора»;
* убраны некоторые неточности и в общем «прилизан» код.

Главный итог: теперь слияние должно происходить несравненно быстрее и быть сопоставимо со скоростью однократного чтения исходных файлов и однократной записи результирующего.

Замечания:
* скрипт предназначен для исполнения под хостом cscript.exe;
* Microsoft в статье LoadFromFile Method в ADO 2.8 SDK пишет:

Because 2 bytes may be added to the beginning of the stream for encoding, the size of the stream may not exactly match the size of the file from which it was loaded.

Надеюсь, что эти байты, даже если и появляются, то также исчезают при записи потока методом SaveToFile.

SplitFile.vbs:

Option Explicit

Const adTypeBinary          = 1
Const adTypeText            = 2

Const adModeRead            = 1
Const adModeWrite           = 2
Const adModeReadWrite       = 3

Const adSaveCreateNotExist  = 1
Const adSaveCreateOverWrite = 2

Const strBatchFileName = "Join.cmd"


Dim objNamedArgs
Dim objWshShell
Dim objFSO
Dim objTS
Dim objStreamSource
Dim objStreamDest

Dim strSourceFile
Dim strDestFolder
Dim lngPartSize
Dim boolNoAskReWrite
Dim boolCreateCMD

Dim intPartNumber
Dim strPartList
Dim boolDone


Set objNamedArgs    = WScript.Arguments.Named
Set objWshShell     = WScript.CreateObject("WScript.Shell")
Set objFSO          = WScript.CreateObject("Scripting.FileSystemObject")
Set objStreamSource = WScript.CreateObject("ADODB.Stream")
Set objStreamDest   = WScript.CreateObject("ADODB.Stream")


If objNamedArgs.Exists("Help") Or objNamedArgs.Exists("?") Then
    ShowUsage
    QuitInfo "", 0, 0
End If

If objNamedArgs.Exists("SourceFile") Then
    strSourceFile = objNamedArgs.Item("SourceFile")
    
    If Not objFSO.FileExists(strSourceFile) Then
        QuitInfo "Исходный файл " & strSourceFile & " не найден", 2, 0
    End If
Else
    ShowUsage
    QuitInfo "Не указан обязательный параметр /SourceFile", 1, 0
End If

If objNamedArgs.Exists("DestFolder") Then
    strDestFolder = objNamedArgs.Item("DestFolder")
Else
    strDestFolder = objWshShell.CurrentDirectory
End If

If objNamedArgs.Exists("PartSize") Then
    lngPartSize = Clng(objNamedArgs.Item("PartSize"))
Else
    lngPartSize = 1457664
End If

If objNamedArgs.Exists("Y") Then
    boolNoAskReWrite = True
Else
    boolNoAskReWrite = False
End If

If objNamedArgs.Exists("Cmd") Then
    boolCreateCMD = True
Else
    boolCreateCMD = False
End If

With WScript.StdOut
    .WriteLine ""
    .WriteLine "Разделение файла на части"
    .WriteLine ""
    .WriteLine "Исходный файл                            : " & strSourceFile
    .WriteLine "Папка назначения для набора              : " & strDestFolder
    .WriteLine "Размер отдельной части набора            : " & FormatNumber(lngPartSize, 0) & " байт"
    .WriteLine "Перезаписывать существующие части набора : " & IIf(boolNoAskReWrite, "Да", "Спросить")
    .WriteLine "Создавать командный файл для слияния     : " & IIf(boolCreateCMD, "Да", "Нет")
    .WriteLine ""
End With

intPartNumber = 1
strPartList = ""
boolDone = False

With objStreamDest
    .Mode = adModeReadWrite
    .Type = adTypeBinary
    
    .Open
End With

With objStreamSource
    .Mode = adModeReadWrite
    .Type = adTypeBinary
    
    .Open
    
    .LoadFromFile strSourceFile
    
    Do
        WritePart objStreamSource
        
        intPartNumber = intPartNumber + 1
    Loop Until .EOS Or boolDone
    
    .Close
End With

With objStreamDest
    .Close
End With

If boolCreateCMD And Not boolDone Then
    Set objTS = objFSO.CreateTextFile(objfso.BuildPath(strDestFolder, strBatchFileName), True, False)
    
    objTS.Write CmdText()
    objTS.Close
    
    Set objTS = Nothing
    
    WScript.Echo
    WScript.Echo "Создан командный файл [" & objfso.BuildPath(strDestFolder, strBatchFileName) & "] для слияния."
End If


Set objStreamDest   = Nothing
Set objStreamSource = Nothing
Set objFSO          = Nothing
Set objWshShell     = Nothing
Set objNamedArgs    = Nothing

If boolDone Then
    QuitInfo vbCrLf & "Обработка была прервана по желанию пользователя.", 0, 1
Else
    QuitInfo vbCrLf & "Готово.", 0, 1
End If

WScript.Quit 0
'=============================================================================

'=============================================================================
Sub WritePart(ByRef objStream)
    Dim strPartNumber
    Dim strDestPartFile
    Dim strAnswer
    
    strPartNumber = Right("0000" & CStr(intPartNumber), Len("0000"))
    strDestPartFile = objFSO.BuildPath(strDestFolder, _
        objFSO.GetFileName(strSourceFile) & ".part" & strPartNumber & ".bin")
    strPartList = strPartList & objFSO.GetFileName(strSourceFile) & ".part" & strPartNumber & ".bin" & vbCrLf
    
    WScript.StdOut.WriteLine "Обрабатывается часть #" & strPartNumber & ": [" & strDestPartFile & "]"
    
    With objStreamDest
        .Write objStream.Read(lngPartSize)
        
        If objFSO.FileExists(strDestPartFile) Then
            If boolNoAskReWrite Then
                .SaveToFile strDestPartFile, adSaveCreateOverWrite
            Else
                Do
                    WScript.StdOut.Write "Файл [" & strDestPartFile & "] существует. Перезаписать? [Y(es)/N(o)/A(ll yes)]:"
                    strAnswer = UCase(Left(WScript.StdIn.ReadLine(), 1))
                    
                    Select Case strAnswer
                        Case "Y"
                            .SaveToFile strDestPartFile, adSaveCreateOverWrite
                            
                            Exit Do
                        Case "N"
                            boolDone = True
                            
                            Exit Do
                        Case "A"
                            .SaveToFile strDestPartFile, adSaveCreateOverWrite
                            boolNoAskReWrite = True
                            
                            Exit Do
                        Case Else
                            ' Nothing to do
                    End Select
                Loop
            End If
        Else
            .SaveToFile strDestPartFile, adSaveCreateNotExist
        End If
        
        .Position = 0
        .SetEOS
    End With
End Sub
'=============================================================================

'=============================================================================
Sub QuitInfo(strInfo, intErrorlevel, intPause)
    With WScript
        If Len(strInfo) <> 0 Then
            If intErrorlevel = 0 Then
                .StdOut.WriteLine strInfo
            Else
                .StdErr.WriteLine strInfo
            End If
        End If
        
        If intPause <> 0 Then
            .Sleep intPause * 1000
        End If
        
        .Quit intErrorlevel
    End With
End Sub
'=============================================================================

'=============================================================================
Sub ShowUsage()
    WScript.StdOut.WriteLine _
        "Использование:" & vbCrLf & _
        "    " & WScript.ScriptName & " /Help | /?" & vbCrLf & _
        "    " & WScript.ScriptName & " /SourceFile:<FileName> [/DestFolder:<Path>] [/PartSize:<Size>] [/Y] [/Cmd]" & vbCrLf & _
        "" & vbCrLf & _
        "Описание     :" & vbCrLf & _
        "    Скрипт " & WScript.ScriptName & " позволяет разделить файл на несколько частей" & vbCrLf & _
        "    (в данной версии скрипта - не более 9999 частей) заданного размера." & vbCrLf & _
        "    Эти части в последующем можно слить в исходный файл с помощью команды" & vbCrLf & _
        "    copy или пакетного файла, создание которого можно задать при разделении." & vbCrLf & _
        "" & vbCrLf & _
        "Параметры    :" & vbCrLf & _
        "/Help или /? : Эта справка." & vbCrLf & _
        "" & vbCrLf & _
        "/SourceFile  : Имя исходного файла для разбиения на части." & vbCrLf & _
        "    Файлы отдельных частей получат имена вида <name.ext.part####.bin>, где:" & vbCrLf & _
        "        name.ext - имя.расширение исходного файла;" & vbCrLf & _
        "        ####     - номер отдельной части исходного файла." & vbCrLf & _
        "    Впоследствии они могут быть склеены в исходный файл <name.ext> командой" & vbCrLf & _
        "        copy /b name.ext.part0001.bin+...+name.ext.partNNNN.bin name.ext" & vbCrLf & _
        "    или copy /b name.ext.part????.bin name.ext (корректное слияние" & vbCrLf & _
        "    в последнем случае гарантируется только для файловой системы NTFS)." & vbCrLf & _
        "    См. также параметр /Cmd ниже." & vbCrLf & _
        "" & vbCrLf & _
        "/DestFolder  : Папка, куда будут помещены отдельные части исходного файла." & vbCrLf & _
        "    Если не указана, будет использована текущая папка." & vbCrLf & _
        "" & vbCrLf & _
        "/PartSize    : Размер отдельной части." & vbCrLf & _
        "    Если не указан, подразумевается размер стандартной 3.5"" дискеты" & vbCrLf & _
        "    - 1.44 Мб (1457664 байт)." & vbCrLf & _
        "" & vbCrLf & _
        "/Y           : Перезаписывать существующие файлы набора без подтверждения." & vbCrLf & _
        "    Если параметр /Y не указан, будет выдан запрос на перезапись" & vbCrLf & _
        "    существующего файла." & vbCrLf & _
        "" & vbCrLf & _
        "/Cmd         : Создать пакетный файл для слияния отдельных частей." & vbCrLf & _
        "    В той же папке, куда будут помещены отдельные части файла, будет создан" & vbCrLf & _
        "    пакетный файл Join.cmd. Чтобы воссоздать исходный файл из набора" & vbCrLf & _
        "    отдельных частей, запустите пакетный файл Join.cmd." & vbCrLf & _
        "    Если параметр /Cmd не указан, пакетный файл не создаётся." & vbCrLf & _
        "" & vbCrLf & _
        "Примеры      :" & vbCrLf & _
        "    " & WScript.ScriptName & " /SourceFile:""c:\My Downloads\K-Lite Codec Pack\klcodec400f.exe""" & vbCrLf & _
        "    " & WScript.ScriptName & " /SourceFile:""c:\xpcd\i386\driver.cab"" /PartSize:5000000" & vbCrLf & _
        "    " & WScript.ScriptName & " /SourceFile:driver.cab /DestFolder:""c:\temp"" /Y /Cmd" & vbCrLf & _
        ""
End Sub
'=============================================================================

'=============================================================================
Function CmdText()
    CmdText = _
        "@echo off" & vbCrLf & _
        "" & vbCrLf & _
        "setlocal enableextensions enabledelayedexpansion" & vbCrLf & _
        "" & vbCrLf & _
        "echo." & vbCrLf & _
        "echo Восстановление исходного файла из частей набора" & vbCrLf & _
        "echo." & vbCrLf & _
        "" & vbCrLf & _
        "if [%1]==[/?] (" & vbCrLf & _
        "    call :Using" & vbCrLf & _
        "    exit /b 0" & vbCrLf & _
        ")" & vbCrLf & _
        "" & vbCrLf & _
        "set strThisFile=%~f0" & vbCrLf & _
        "for /f ""delims=[]"" %%i in ('find.exe /n /i ""rem JoinList"" ""%strThisFile%""') do set intLine=%%i" & vbCrLf & _
        "" & vbCrLf & _
        "for /f ""skip=%intLine% delims="" %%i in (%strThisFile%) do (" & vbCrLf & _
        "    set strPartFileName=%%~ni" & vbCrLf & _
        "    set strPartFileTemplate=!strPartFileName:~0,-4!????%%~xi" & vbCrLf & _
        ")" & vbCrLf & _
        "set strRealFileName=%strPartFileName:~0,-9%" & vbCrLf & _
        "" & vbCrLf & _
        "echo Поиск отсутствующих частей:" & vbCrLf & _
        "" & vbCrLf & _
        "for /f ""skip=%intLine% delims="" %%i in (%strThisFile%) do (" & vbCrLf & _
        "    if exist ""%%i"" (" & vbCrLf & _
        "        echo %%i : Ok" & vbCrLf & _
        "    ) else (" & vbCrLf & _
        "        echo %%i : Отсутствует" & vbCrLf & _
        "        set IsLost=True" & vbCrLf & _
        "    )" & vbCrLf & _
        ")" & vbCrLf & _
        "" & vbCrLf & _
        "if defined IsLost (" & vbCrLf & _
        "    echo Отсутствуют некоторые части набора. Продолжение работы невозможно." & vbCrLf & _
        "    exit /b 1" & vbCrLf & _
        ") else (" & vbCrLf & _
        "    echo Присутствуют все части набора." & vbCrLf & _
        ")" & vbCrLf & _
        "" & vbCrLf & _
        "echo." & vbCrLf & _
        "echo Слияние частей набора:" & vbCrLf & _
        "" & vbCrLf & _
        "set strWorkFolder=$Temp%random%" & vbCrLf & _
        "" & vbCrLf & _
        "md "".\!strWorkFolder!""" & vbCrLf & _
        "cd "".\!strWorkFolder!""" & vbCrLf & _
        "" & vbCrLf & _
        "for /f ""skip=%intLine% delims="" %%i in (%strThisFile%) do move ""..\%%i"" "".\""" & vbCrLf & _
        "copy /b /y ""%strPartFileTemplate%"" ""..\%strRealFileName%""" & vbCrLf & _
        "for /f ""skip=%intLine% delims="" %%i in (%strThisFile%) do move ""%%i"" ""..\""" & vbCrLf & _
        "" & vbCrLf & _
        "cd ""..""" & vbCrLf & _
        "rd /s /q "".\!strWorkFolder!""" & vbCrLf & _
        "" & vbCrLf & _
        "echo." & vbCrLf & _
        "echo Процесс слияния завершён." & vbCrLf & _
        "echo." & vbCrLf & _
        "echo Имя исходного файла: %strRealFileName%" & vbCrLf & _
        "" & vbCrLf & _
        "endlocal" & vbCrLf & _
        "exit /b 0" & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        "" & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        ":Using" & vbCrLf & _
        "    echo Использование:  %~nx0" & vbCrLf & _
        "    echo." & vbCrLf & _
        "    echo При отсутствии хотя бы одной из отдельных частей набора обработка завершается." & vbCrLf & _
        "    exit /b 0" & vbCrLf & _
        "::============================================================================" & vbCrLf & _
        "" & vbCrLf & _
        "rem ==========================================================================" & vbCrLf & _
        "rem JoinList" & vbCrLf & _
        strPartList
        
    CmdText = StrConvert(CmdText, "cp866", "Windows-1251")
End Function
'=============================================================================

'=============================================================================
Function StrConvert(strText, strSourceCharset, strDestCharset)
    Const adTypeText      = 2
    Const adModeReadWrite = 3
    
    
    With WScript.CreateObject("ADODB.Stream")
        .Type      = adTypeText
        .Mode      = adModeReadWrite
        
        .Open
        
        .Charset   = strSourceCharset
        .WriteText strText
        
        .Position  = 0
        .Charset   = strDestCharset
        StrConvert = .ReadText
        
        .Close
    End With
End Function
'=============================================================================

'=============================================================================
Function IIf(strIF, strThen, strElse)
    If Eval(strIF) Then
        If VarType(strThen) = vbString Then
            IIf = strThen
        Else
            IIf = Eval(strThen)
        End If
    Else
        If VarType(strElse) = vbString Then
            IIf = strElse
        Else
            IIf = Eval(strElse)
        End If
    End If
End Function
'=============================================================================

P.S. Тут, конечно, больше новведений на тему CMD/BAT, но так уж сложилось.
P.P.S. Файл размером 727,713,948 байт был разбит скриптом на 3639 частей ~ за 3.5 минуты. Слияние завершилось ~ за 6.5 минут.
Intel(R) Pentium(R) D CPU 3.00GHz, 2048 MB ОЗУ (DDR2 PC2-6400 (400 MHz), 4x512 MBytes, Kingston), SATA-1 RAID Level 1 (2xST3250823AS), Windows XP SP3.

Отдельное спасибо The gray Cardinal, Diamond.