Powershell의 빠르고 간단한 이진 연결 파일
파워셸을 사용하여 이진 파일을 연결하는 가장 좋은 방법은 무엇입니까?기억하기 쉽고 실행이 빠른 원라이너를 선호합니다.
제가 생각해낸 최고의 것은:
gc -Encoding Byte -Path ".\File1.bin",".\File2.bin" | sc -Encoding Byte new.bin
이것은 잘 작동하는 것처럼 보이지만 큰 파일에서는 매우 느립니다.
PowerShell을 사용하는 방법은 제가 PowerShell을 사용하는 방법입니다.그러나 성능을 향상시키려면 -ReadCount 매개 변수를 사용해야 합니다.또한 위치 매개 변수를 활용하여 이를 더욱 단축할 수 있습니다.
gc File1.bin,File2.bin -Encoding Byte -Read 512 | sc new.bin -Encoding Byte
편집자 참고 사항:크로스 플랫폼 PowerShell(Core) 버전(버전 6 이상)에서는-AsByteStream
이제 대신 사용해야 합니다.-Encoding Byte
또한, 그sc
cmdlet의 별칭이 제거되었습니다.
-ReadCount 매개변수의 사용과 관련하여, 저는 얼마 전에 사람들이 유용하다고 생각할 수 있는 블로그 게시물 - 대용량 파일에 대한 콘텐츠 가져오기 성능 최적화.
Powershell은 아니지만 Powershell이 있으면 다음 명령 프롬프트도 표시됩니다.
copy /b 1.bin+2.bin 3.bin
Keith Hill이 지적했듯이 Powershell 내부에서 실행해야 하는 경우 다음을 사용할 수 있습니다.
cmd /c copy /b 1.bin+2.bin 3.bin
최근에 비슷한 문제가 있었습니다. 두 개의 대용량(2GB) 파일을 하나의 파일(4GB)에 추가해야 했습니다.
Get-Content에 대한 -ReadCount 매개 변수를 조정하려고 했지만 큰 파일의 성능을 향상시킬 수 없었습니다.
저는 다음과 같은 솔루션을 사용했습니다.
function Join-File (
[parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true)]
[string[]] $Path,
[parameter(Position=1,Mandatory=$true)]
[string] $Destination
)
{
write-verbose "Join-File: Open Destination1 $Destination"
$OutFile = [System.IO.File]::Create($Destination)
foreach ( $File in $Path ) {
write-verbose " Join-File: Open Source $File"
$InFile = [System.IO.File]::OpenRead($File)
$InFile.CopyTo($OutFile)
$InFile.Dispose()
}
$OutFile.Dispose()
write-verbose "Join-File: finished"
}
성능:
cmd.exe /c copy file1+file2 File3
약 5초(최적)gc file1,file2 |sc file3
약 1100초(요크)join-file File1,File2 File3
약 16초(OK)
성능은 사용되는 버퍼 크기에 따라 크게 달라집니다.기본적으로 상당히 작은 크기입니다.2GB 파일 2개를 연결하면 약 256kb의 버퍼 크기가 됩니다.크기를 크게 하면 때로는 실패하거나 작게 하면 드라이브의 처리 능력보다 더 적은 처리량을 얻을 수 있습니다.
와 함께gc
그것으로-ReadCount
단순한 것이 아닌-Read
(PowerShell 5.0):
gc -ReadCount 256KB -Path $infile -Encoding Byte | ...
내가 찾은 것도Add-Content
많은 작은 파일을 파일 단위로 저장하는 것이 더 낫습니다. 적당한 양의 데이터(200MB)만 파이프로 연결하면 컴퓨터가 정상적으로 작동하고 PowerShell이 동결되고 CPU가 가득 찼기 때문입니다.
비록 ~일지라도Add-Content
대상 파일이 사용 중이라는 오류와 함께 수백 개의 파일에 대해 무작위로 몇 번 실패했기 때문에 잠시 루프와 시도 캐치를 추가했습니다.
# 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 {
}
}
}
파일 스트림을 사용하는 것이 훨씬 빠릅니다.는 " " " " " 로 할 수 .[System.IO.File]::Open
하지만 당신은 할 수 있습니다.new [System.IO.FileStream]
예:
# $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()
}
언급URL : https://stackoverflow.com/questions/1783554/fast-and-simple-binary-concatenate-files-in-powershell
'source' 카테고리의 다른 글
Javascript에서 HTTP 특정 헤더를 제거하는 방법 (0) | 2023.08.25 |
---|---|
jQuery 데이터 속성 값으로 요소 찾기 (0) | 2023.08.25 |
PowerShell: 헤더가 없는 형식 테이블 (0) | 2023.08.25 |
클러스터에서 Galera 노드 제거 (0) | 2023.08.25 |
Angular 9는 로드해야 하는 글로벌 '$localize()' 함수를 도입했습니다. (0) | 2023.08.25 |