El rendimiento depende en gran medida del tamaño del búfer utilizado. Esas son bastante pequeñas por defecto. Concatenar archivos de 2x2GB tomaría un buffer de aproximadamente 256kb. En ocasiones, una mayor potencia puede fallar, ser más pequeña y obtener un rendimiento menor de lo que su unidad es capaz de hacer.
Con gc
que estaría con -ReadCount
no simplemente -Read
(PowerShell 5.0):
gc -ReadCount 256KB -Path $infile -Encoding Byte | ...
Además me encontré Add-Content
a ser mejor y archivo por archivo en busca de un montón de archivos pequeños, porque las tuberías solo una cantidad moderada de datos (200 MB) encontré que mi computadora estaba en funcionamiento, la congelación de PowerShell y la CPU estaban llenos.
Aunque Add-Content
falla al azar un par de veces para unos pocos cientos de archivos con un error sobre el archivo de destino de estar en uso, por lo que añade un bucle while y un intento de captura:
# Empty the file first
sc -Path "$path\video.ts" -Value @() -Encoding Byte
$tsfiles | foreach {
while ($true) {
try { # I had -ReadCount 0 because the files are smaller than 256KB
gc -ReadCount 0 -Path "$path\$_" -Encoding Byte | `
Add-Content -Path "$path\video.ts" -Encoding Byte -ErrorAction Stop
break;
} catch {
}
}
}
usando una secuencia de archivo es mucho más rápido aún No se puede especificar un tamaño de búfer con [System.IO.File]::Open
pero puede hacerlo con new [System.IO.FileStream]
así:
# $path = "C:\"
$ins = @("a.ts", "b.ts")
$outfile = "$path\out.mp4"
$out = New-Object -TypeName "System.IO.FileStream" -ArgumentList @(
$outfile,
[System.IO.FileMode]::Create,
[System.IO.FileAccess]::Write,
[System.IO.FileShare]::None,
256KB,
[System.IO.FileOptions]::None)
try {
foreach ($in in $ins) {
$fs = New-Object -TypeName "System.IO.FileStream" -ArgumentList @(
"$path\$in",
[System.IO.FileMode]::Open,
[System.IO.FileAccess]::Read,
[System.IO.FileShare]::Read,
256KB,
[System.IO.FileOptions]::SequentialScan)
try {
$fs.CopyTo($out)
} finally {
$fs.Dispose()
}
}
} finally {
$out.Dispose()
}
Acabo de ejecutar esto en mis archivos de ejemplo y el comando pasó de tomar 9 minutos a 3 segundos con la inclusión del parámetro -read. Esto está en una unidad x25m. Bonito. Consigues mi aceptar. – FkYkko
Acabo de utilizar su one-liner para unir una iso de 4.4 gb distribuida en más de 23 archivos. Reensamblé bien el archivo y tardé 35 minutos en mi computadora portátil usando bloques de 1024 bytes. –
Supongo que esto funciona porque la pipa está enviando objetos .net a sc? Cuando traté de canalizar datos binarios a un programa c, noté que solo obtuve los primeros 7 bits de cada byte, ya que "|" invocó la codificación. – johnnycrash