DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ランダムアクセス

環境/言語:[Win]
分類:[.NET]

kageです、お世話になります。

固定長文字列についての質問です。
VB6のModuleに次のように記述してグローバル変数として使っていました。
Global AA(50) As String * 3

これをVB.NETで
<VBFixedString(3)> Public AA(50) As String
と書き換え、次のように読み込みをしようとするとエラーになります。
FileOpen(1, "C:\Temp.txt", OpenMode.Random, , , 3)
For n = 1 To 50
FileGet(1, AA(n), n)
Next n
FileClose(1)
どのように書いていいか分かりません。よろしくお願いします。
kageさん、こんにちは。

どうしてエラーになるのかは検証していませんが、.NET風に書くなら次のようになります。
関係ないかもしれませんが、VB6互換モードを使うと大きなファイルの読み書きは処理が遅くなります。
できるだけVB6互換モードの使用は避けた方がいいでしょう。


Imports System.IO

Dim AA(49) As String
Dim n As Integer
Dim BynaryFile As BinaryReader
Dim FS As FileStream
Dim sjisEnc As System.Text.Encoding
Dim bytAA(2) As Byte

sjisEnc = System.Text.Encoding.GetEncoding("Shift_JIS")

FS = New FileStream("C:\Temp.txt", FileMode.OpenOrCreate)
BynaryFile = New BinaryReader(FS)

With BynaryFile
For n = 0 To 49
bytAA = .ReadBytes(3)
AA(n) = sjisEnc.GetString(bytAA)
Next n
End With

BynaryFile.Close()
ポンさん、お世話になります。

> できるだけVB6互換モードの使用は避けた方がいいでしょう。

私も、そのようにしたいのです。
いただいたコードを試してみましたところ、確かにきっちりと作動しました。
が、何度見ても次の構文が理解できません。

> Dim bytAA(2) As Byte

> AA(n) = sjisEnc.GetString(bytAA)

ついでに、ランダムアクセスのWriteに挑戦してみましたが、さっぱり分かりませんでした。
こちらについても、ご協力いただけると幸いです。 kage
kageさん、こんにちは。

> が、何度見ても次の構文が理解できません。
>
>>Dim bytAA(2) As Byte
>
>>AA(n) = sjisEnc.GetString(bytAA)
>

いったん、ファイルからByte型配列に読み込んで、Shift JIS形式の文字列に変換しているだけです。
DOBONさんの.NET Tips「文字コードを指定してテキストファイルに書き込む」
http://dobon.net/vb/dotnet/file/writefile.html に解説があります。



> ついでに、ランダムアクセスのWriteに挑戦してみましたが、さっぱり分かりませんでした。
> こちらについても、ご協力いただけると幸いです。 kage
>

Writeについてはこんなかんじです。

Dim AA(49) As String
Dim n As Integer
Dim BynaryFile As BinaryWriter
Dim FS As FileStream
Dim sjisEnc As System.Text.Encoding
Dim bytAA(2) As Byte

'AA(n) Is Nothing の時はエラーになるので適用な文字を入れます
For n = 0 To 49
AA(n) = n.ToString + "00"
Next

sjisEnc = System.Text.Encoding.GetEncoding("Shift_JIS")

FS = New FileStream("C:\Temp.txt", FileMode.OpenOrCreate)
BynaryFile = New BinaryWriter(FS)

With BynaryFile
For n = 0 To 49
.Seek(3 * n, SeekOrigin.Begin)
bytAA = sjisEnc.GetBytes(AA(n))
ReDim Preserve bytAA(2)
.Write(bytAA)
Next n
End With

BynaryFile.Close()


※ ReDim Preserve bytAA(2) としているのは、文字が1byte分しかない場合や5byteある場合に、
強制的に3byteにします。すべてのレコードが3Byteに揃えられているときには必要ないです。
※ .Seek(3 * n, SeekOrigin.Begin) は上記のように連続して書き込む場合は必要ないです。
10-15行目だけ上書きしたい場合には必要です。
ポンさん、お世話になります。

> いったん、ファイルからByte型配列に読み込んで、Shift JIS形式の文字列に変換しているだけです。

理解できなかったのは、bytAAは配列変数なのに、配列を使わないで使うということを今までした事がなかったものですから。

いただいたコードをいろんな角度で試してみました。
お陰さまできっちりランダムアクセスができるようになりました。
ありがとうございました。   kage
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板