Моя вимога була дещо іншою. Я часто працюю з ASCII-файлами, розділеними комами та розділеними табуляцією, де один рядок - це єдиний запис даних. І вони справді великі, тому мені потрібно розділити їх на керовані частини (зберігаючи рядок заголовка).
Отже, я повернувся до свого класичного методу VBScript і об’єднав невеликий скрипт .vbs, який можна запустити на будь-якому комп’ютері Windows (він автоматично виконується двигуном хосту сценарію WScript.exe у вікні).
Перевага цього методу полягає в тому, що він використовує текстові потоки, тому базові дані не завантажуються в пам'ять (або, принаймні, не всі одночасно). Результат полягає в тому, що це надзвичайно швидко, і йому не потрібно багато пам'яті для роботи. Тестовий файл, який я щойно розбив за допомогою цього сценарію на моєму i7, був розміром близько 1 ГБ, мав близько 12 мільйонів рядків тесту і створив 25 файлів деталей (кожен з яких приблизно по 500 тисяч рядків) - обробка зайняла близько 2 хвилин, і це не зробило не перевищує 3 Мб пам'яті, що використовується в будь-який момент.
Застереження тут полягає в тому, що він покладається на текстовий файл, що має "рядки" (тобто кожен запис розмежовується CRLF), оскільки об'єкт Text Stream використовує функцію "ReadLine" для обробки окремих рядків за раз. Але привіт, якщо ви працюєте з файлами TSV або CSV, це ідеально.
Option Explicit
Private Const INPUT_TEXT_FILE = "c:\bigtextfile.txt" 'The full path to the big file
Private Const REPEAT_HEADER_ROW = True 'Set to True to duplicate the header row in each part file
Private Const LINES_PER_PART = 500000 'The number of lines per part file
Dim oFileSystem, oInputFile, oOutputFile, iOutputFile, iLineCounter, sHeaderLine, sLine, sFileExt, sStart
sStart = Now()
sFileExt = Right(INPUT_TEXT_FILE,Len(INPUT_TEXT_FILE)-InstrRev(INPUT_TEXT_FILE,".")+1)
iLineCounter = 0
iOutputFile = 1
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
Set oInputFile = oFileSystem.OpenTextFile(INPUT_TEXT_FILE, 1, False)
Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True)
If REPEAT_HEADER_ROW Then
iLineCounter = 1
sHeaderLine = oInputFile.ReadLine()
Call oOutputFile.WriteLine(sHeaderLine)
End If
Do While Not oInputFile.AtEndOfStream
sLine = oInputFile.ReadLine()
Call oOutputFile.WriteLine(sLine)
iLineCounter = iLineCounter + 1
If iLineCounter Mod LINES_PER_PART = 0 Then
iOutputFile = iOutputFile + 1
Call oOutputFile.Close()
Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True)
If REPEAT_HEADER_ROW Then
Call oOutputFile.WriteLine(sHeaderLine)
End If
End If
Loop
Call oInputFile.Close()
Call oOutputFile.Close()
Set oFileSystem = Nothing
Call MsgBox("Done" & vbCrLf & "Lines Processed:" & iLineCounter & vbCrLf & "Part Files: " & iOutputFile & vbCrLf & "Start Time: " & sStart & vbCrLf & "Finish Time: " & Now())
split
(утиліту Unix / Linux), але тегомbatch-file
якого є Windows.