TheIncorrigible1 предоставил критический указатель в комментарии:
Предполагая, что ваш большой XML-файл все еще может быть загружен в System.Xml.XmlDocument
экземпляр в целом , вы можете просто вызвать его метод .Save()
для создания выходного файла Pretty-Printed (который устраняет необходимость ручной вставки новой строки; плюс, использование парсера XMLвсегда предпочтительнее, чем манипулирование текстом).
# Load the file into a [xml] (System.Xml.XmlDocument) instance...
($xmlDoc = New-Object xml).Load($PWD.ProviderPath + '/HugeFile.xml')
# ... and save it, which automatically pretty-prints it.
$xmlDoc.Save($PWD.ProviderPath + '/HugeFilePrettyPrinted.xml')
Обратите внимание на необходимость добавить $PWD.ProviderPath
к именам файлов, чтобы убедиться, что .NET использует текущий каталог PowerShell (обычно .NET отличается, а .NET не делает)t знать о дисках PowerShell, созданных с помощью New-PSDrive
). [1]
Примечание. Полученный файл будет содержать только новые строки LF, а не CRLF.
A технико-экономическое обоснование :
Сначала запустите следующий код (PSv5 +), чтобы создать образец XML-файла , размер которого составляет около 280 МБ.Обратите внимание, что вы можете легко настроить код для указания другого целевого размера.
Примечание:
Файл HugeFile.xml
будет создан в текущем каталоге и запуститсяКоманда pretty-printing позже создает (еще больше) HugeFilePrettyPrinted.xml
в том же месте.
Создание этого файла может занять несколько минут.
# Create a sample single-line XML file of a given size (approximately).
# Note: Depending on the target size, this can take a long time to complete.
# Additionally, for performance reasons the code is written so that
# the file content must fit into memory as a whole.
# The desired size of the resulting file.
$targetFileSize = 280mb
$targetFile = './HugeFile.xml'
# The XML element to repeat.
$repeatingElementTemplate = '<book><title>De Profundis {0:000000000000}</title></book>'
# Determine how often it must be repeated to reach the target size (approximately)
$repeatCount = $targetFileSize / ($repeatingElementTemplate.Length - 4)
Write-Verbose -vb "Creating XML file '$targetFile' of approximate size $('{0:N2}' -f ($targetFileSize / 1mb)) MB..."
# Create the file.
'<?xml version="1.0"?><catalog>' | Set-Content -NoNewline -Encoding Utf8 $targetFile
-join (1..$repeatCount).ForEach({ $repeatingElementTemplate -f $_ }) |
Add-Content -NoNewline -Encoding Utf8 $targetFile
'</catalog>' | Add-Content -NoNewline -Encoding Utf8 $targetFile
Затем выполните команду pretty-printing выше.
На моей одноядерной виртуальной машине Windows 10 с 3 ГБ ОЗУ (на старом оборудовании) это заняло около 40 секунд.Сам Эрик сообщает о своем компьютере менее чем за 5 секунд.
[1] Обеспечение правильной передачи относительного пути файловой системы PowerShell в метод .NET :
Как уже говорилось, представление текущего каталога в .NET обычно отличается от представления PowerShell, поэтому относительные пути PowerShell нельзя использовать как есть.
Формирование полногопуть с $PWD.ProviderPath
($PWD.ProviderPath + '<fileInCurrentDir>
) гарантирует, что текущее местоположение файловой системы PowerShell выражается как собственный путь к файловой системе (спасибо, TheIncorrigible1).Методы .NET понимают только последнее;они не знают о пользовательских дисках PowerShell, созданных с помощью New-PSDrive
, и не знают нотацию с префиксом поставщика PowerShell, которая $PWD
соответствует тому, когда текущим местоположением является путь UNC (например,
Microsoft.PowerShell.Core\FileSystem::\\some-server\some-share\some-folder
).
Если вы не используете собственные диски PowerShell и не запускаете свой код непосредственно из UNC-местоположений, вы можете проще построить полный путь на основе текущего местоположенияс
"$PWD/<fileInCurrentDir>"
.
И наоборот, для полная надежность вам придется использовать
(Get-Location -PSProvider FileSystem).ProviderPath + '/<fileInCurrentDir>'
, учитывая, что текущее местоположение PowerShell может быть одним из от поставщика другой , чем поставщик файловой системы;например, HKCU:\Console
(поставщик реестра).