投稿者 KOZ  (社会人) 投稿日時 2022/10/19 20:10:42
FileStream.Read メソッドの第2引数は、読み込んだデータを格納するバッファの位置を示します。

readSize = fs.Read(buf, bufPos, Math.Min(528, remain));

ここで buf の 読み込み位置をずらしているのに、

Marshal.Copy(buf, 0, ptr, size);

buf の先頭から変換しているので、毎回1件目が表示されることになります。

第2引数をゼロにすれば、とりあえず動きます。

あと修正すべきなのは

・528 と定数を使うのは良くない。

int structSize = Marshal.SizeOf(typeof(Form1.usrData));

として structSize を使う

・buf の長さは 528 バイトで良い

byte[] buf = new byte[structSize]; 

・remain は不要。 

readSize = fs.Read(buf, 0, structSize);

として、readSize = 0 ならループを抜ければよい。

ファイルの残りが structSize より小さい場合は buf にその分だけ読み込まれ、読み込んだサイズが readSize に入る
readSize が structSize より小さい値のとき、どうするのか仕様を決めること。

・ Marshal.AllocHGlobal に対する Marshal.FreeHGlobal が無い

IntPtr ptr = Marshal.AllocHGlobal(structSize);
try {

} finally {
    Marshal.FreeHGlobal(ptr);
}

のように使う。
また、毎回確保する必要は無いので try ブロックの中にループを入れてしまえば良い。

・ fs.Dispose() したら fs.Close() は不要。