ファイルの読み/書き
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