ファイルの読み/書き

Binary-RW.ps1

# ファイルの読み/書き # 戻り値 # 書き込み時は戻り値なし # 読み込み時は読み込んだデータを格納するバイト配列 # -target # 書き込み/読み込み対象のファイル・パス # 書き込み時では、ファイルが存在しない場合は作成する # -offset # 書き込み/読み込み位置。0 以上 # -size # 読み込み用。読み込みサイズ。1 以上 # -data # 省略すると読み込み # 指定すると書き込み # 指定できるのはバイト配列、または 16 進数で構成する文字列 Param( [string] $target, [int] $offset, [int] $size, $data ) trap { break } # エラー・メッセージ出力 Function ErrorMsg( [string] $s ) { Write-Host $s } # メッセージ出力 Function OutputMsg( $s ) { $s | Write-Host } # ファイル・オープン。 # 読み込み時は、ファイルが存在していなければならない # 書き込み時は、存在しなければ作成する # -path # ファイル・パス # -write # 指定すると書き込み、省略すると読み込み Function Open-File( $path, [Switch] $write ) { try { $pathCurrent = [System.IO.Directory]::GetCurrentDirectory() [System.IO.Directory]::SetCurrentDirectory( (Get-Location) ); if( $write.IsPresent ) { $FileMode = [System.IO.FileMode]::OpenOrCreate $FileAccess = [System.IO.FileAccess]::Write } else { $FileMode = [System.IO.FileMode]::Open $FileAccess = [System.IO.FileAccess]::Read } $fSrc = [System.IO.File]::Open( $path, $FileMode, $FileAccess ) if( $write.IsPresent ) { [System.IO.BinaryWriter]::new( $fSrc ) } else { [System.IO.BinaryReader]::new( $fSrc ) } } catch [System.Exception] { if( $fSrc -ne $Null ) { $fSrc.Dispose() } $Null } finally { [System.IO.Directory]::SetCurrentDirectory( $pathCurrent ) } } # フィルター。 # バイト配列を 16 進数の文字列に変換する Function BytesToHEX { Begin { $bufferTxt = '' } Process { $bufferTxt += $_.ToString( 'X2' ) } End { $bufferTxt } } # フィルター。 # バイト配列を 16 進数の文字列に変換する # -s # 16 進数を表す文字列 Function CheckHEX( [string] $s ) { if( $s -match "^([0-9A-Fa-f]{2})+$" ) { $True } else { $False } } # 文字列(16 進数を表す)をバイト配列にする # -s # 16 進数を表す文字列 Function HEXToBytes( [string] $s ) { $buffer = New-Object "byte[]" ($s.Length -shl 1) $y = 0 for( $x = 0; $x -lt $s.Length; $x += 2 ) { $buffer[ $y ] = [byte]::Parse( $s.Substring($x, 2), [System.Globalization.NumberStyles]::HexNumber ) $y ++ } $buffer } # $data が有効なものか確認する # バイト配列、16 進数を表す文字列の場合、有効となる # # 戻り値 # $Null の場合は $data が不正 # バイト配列の場合は正。$data をバイト配列に変換したもの # -data # 任意の値 Function CheckData( $data ) { if( $data.GetType() -eq [byte[]] ) { return $data } if( $data.GetType() -eq [string] ) { $r = CheckHEX $data if( $r -eq $False ) { return $Null } return HEXToBytes $data } $Null } # ターゲット・ファイルの存在を確認する if( $target.Length -eq 0 ) { OutputMsg "書式", "Binary-RW [-target] ファイル [-offset] <オフセット> [-size <サイズ>] [-data <value>]" return } if( $size -lt 0 ) { ErrorMsg "-size の指定は不正です" return } if( $offset -lt 0 ) { ErrorMsg "-offset の指定は不正です" return } # コマンドレットへの引数を確認する if( $data -eq $Null ) { # 読み込み時 # 処理なし } else { # 書き込み時 $bufferHex = CheckData $data if( $bufferHex -eq $Null ) { ErrorMsg "-data の指定が不正です" return } } # メイン if( $data -eq $Null ) { # 読み込み時 [System.IO.BinaryReader] $fr = Open-File $target if( $fr -eq $Null ) { ErrorMsg "読み込みオープンできません" return } if( $fr.BaseStream.Length -lt ($offset + $size) ) { $fr.Dispose() ErrorMsg "-offset / -size の指定が不正です" return } [byte[]] $bufferHex = New-Object "byte[]" $size $fr.BaseStream.Position = $offset [void] $fr.Read( [byte[]] $bufferHex, 0, $bufferHex.Length ) $fr.Dispose() $bufferHex } else { # 書き込み時 [System.IO.BinaryWriter] $fw = Open-File $target -write if( $fw -eq $Null ) { ErrorMsg "書き込みオープンできません" return } $fw.BaseStream.Position = $offset $fw.Write( [byte[]] $bufferHex, 0, $bufferHex.Length ) $fw.Dispose() }

使用サンプル

# 使用例(書き込み、文字列指定) Binary-RW State01.bin 32 -data:"ff01020304050607" # 使用例(読み込み。byte[] でキャストすることが大事!) [byte[]] $m = Binary-RW State01.bin 16 -size:8 # 使用例(書き込み、バイト配列指定) Binary-RW State01.bin 48 -data:$m