Ich arbeite mit einigen Multi-Gigabyte-Textdateien und möchte mit PowerShell Stream-Verarbeitung für sie durchführen. Es ist ganz einfach, jede Zeile zu analysieren, einige Daten abzurufen und sie dann in einer Datenbank zu speichern.
Leider get-content | %{ whatever($_) }
scheint der gesamte Satz von Zeilen in dieser Phase der Pipe im Speicher zu bleiben. Es ist auch überraschend langsam und es dauert sehr lange, alles tatsächlich einzulesen.
Meine Frage besteht also aus zwei Teilen:
- Wie kann ich dafür sorgen, dass der Stream zeilenweise verarbeitet wird und nicht das gesamte Objekt im Speicher gepuffert wird? Ich möchte vermeiden, mehrere GB RAM für diesen Zweck zu verbrauchen.
- Wie kann ich es schneller laufen lassen? PowerShell, das über a iteriert,
get-content
scheint 100-mal langsamer zu sein als ein C # -Skript.
Ich hoffe, ich mache hier etwas Dummes, wie das Fehlen eines -LineBufferSize
Parameters oder so ...
Get-Content
einer Variablen zuzuweisen, da dadurch die gesamte Datei in den Speicher geladen wird. Standardmäßig Get-Content
verarbeitet die Datei in einer Pipleline zeilenweise. Solange Sie die Ergebnisse nicht akkumulieren oder ein intern akkumuliertes Cmdlet verwenden (wie Sort-Object und Group-Object), sollte der Speicher-Hit nicht zu schlecht sein. Foreach-Object (%) ist eine sichere Methode, um jede Zeile einzeln zu verarbeiten.
get-content | % -End { }
es sich beschwert , wenn Sie versuchen, es zu verwenden , weil Sie keinen Prozessblock angegeben haben. Daher kann standardmäßig nicht -End verwendet werden, sondern standardmäßig -Process. Und versuchen Sie zu 1..5 | % -process { } -end { 'q' }
sehen, dass der gc | % { $_ }
Endblock nur einmal vorkommt. Das Übliche würde nicht funktionieren, wenn der Skriptblock standardmäßig -End ...
get-content
, setzen Sie -ReadCount auf 512. Beachten Sie, dass $ _ im Foreach zu diesem Zeitpunkt ein Array von Zeichenfolgen ist.