文字コードがShift-JISだとすると、読み込んで1行を文字列として扱う分にはSyste.IO.StreamReaderで文字コードを指定してあげれば、よいです。
しかし、固定長の場合、読み込んだレコードをバイト指定で特定の位置にある項目を切り出す必要があり、Shift-JISから別な文字コードに変換されるとバイト数が変化してしまうので、よろしく無いです。
しかし、固定長の場合、読み込んだレコードをバイト指定で特定の位置にある項目を切り出す必要があり、Shift-JISから別な文字コードに変換されるとバイト数が変化してしまうので、よろしく無いです。
ということで、テキストファイルをバイナリとして読み込む必要があります。
面倒ではありますが、項目ごとにバイト配列を用意し、その配列へバイト単位でコピーしその後文字コードを変換してあげることで、レコードの任意の位置から項目を切り出すことが出来ます。
ファイル全体を読み込みますので行の区切りである改行を意識する必要がありますが、固定長の場合一定間隔で改行が現れますので、比較的処理はしやすいです。
<#
.SYNOPSIS
固定長のテキストファイルの読み込み
#>
Param(
[string]$textPath = "C:\WORK\SAMPLE.txt"
)
$width = 138 # レコードの長さ
$bytes = [System.IO.File]::ReadAllBytes($textPath)
[byte[]]$buff = 0..($width-2) # -2は改行CRLFを想定
for ($i = 0; $i -lt $bytes.Length; $i = $i + $width)
{
for($j = 0; $j -le ($width-2); $j = $j + 1)
{
$buff[$j] = $bytes[$i+$j]
}
$enc = [System.Text.Encoding]::GetEncoding("Shift_JIS")
$str = $enc.GetString($buff)
Write-Host ($str)
}
サンプルでは$buffを1行単位に切り出していますが、実際は項目数分$buffを用意し切り出して、文字コードの変換や数字を数値に変換などをしてあげることになります。
感想として、無理にPowerShellを使わず、別なツールで固定長からCSV形式にしてあげてから、PowerShellで処理した方が仕事が早いような気がします。
コメント