1. 파일 분할하기
.net의 System.IO.File 클래스를 활용하여 500MiB 단위로 파일을 분할하는 코드입니다. 원본 파일을 2MB씩 읽고 쓰는 이유는 파워셸이 너무 큰 배열을 다룰 수 없기 때문이고, 아마 다른 스크립트 언어도 비슷한 한계를 가지고 있을 것 같습니다. 시스템 메모리가 한정되어 있다는 것도 이유 중 하나입니다. 아래 코드를 실행하면 다운로드 폴더 내의 지정된 파일이 "파일명_part00" 여러 개로 분할됩니다.
$file = Read-Host -Prompt "Enter file name to split."
$srcFile = "$env:userprofile\Downloads\$file"
$outFilePrefix = "$env:userprofile\Downloads\$file"+"_part"
$chunkSize = 500MB
$bufferSize = 2MB
$buffer = New-Object byte[] $bufferSize
$inputStream = [System.IO.File]::OpenRead($srcFile)
$chunkIndex = 0
while($inputStream.Position -lt $inputStream.Length) {
$outFile = "{0}{1:D2}" -f $outFilePrefix, $chunkIndex
$outStream = [System.IO.File]::Create($outFile)
$bytesWritten = 0
while( `
$bytesWritten -lt $chunkSize `
-and ($read = $inputStream.Read($buffer, 0, $bufferSize)) `
-gt 0) {
$outStream.Write($buffer, 0, $read)
$bytesWritten += $read
}
$outStream.Close()
$chunkIndex++
}
$inputStream.Close()
2. 파일 병합하기
파일을 합치는 코드는 분할하는 코드보다 쉽습니다. 자료구조의 한계로 인해 chunk를 2MB 단위로 읽고 쓰는 부분 없이 그저 chunk를 순서대로 읽어들여 쓰기만 하면 됩니다.
$file = Read-Host -Prompt "Enter file name to merge."
$parts = ls "$env:userprofile\Downloads\$file*part*" | sort Name
$outFile = "$env:userprofile\Downloads\$file"
$outStream = [System.IO.File]::Create($outFile)
foreach ($part in $parts) {
$bytes = [System.IO.File]::ReadAllBytes($part.FullName)
$outStream.Write($bytes, 0, $bytes.Length)
}
$outStream.Close()
3. 파일 해시 검사하기
윈도우에는 파일 해시를 검사할 수 있는 프로그램이 기본적으로 포함되어 있습니다. 바로 certutil.exe입니다. 사용 방법은 아래와 같습니다. 원본 파일과 분할/병합을 거친 파일의 무결성을 검사해 봅시다.
certutil.exe -hashfile <파일명> <해시 알고리즘>