C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

BigEndianでデータを読み込む方法

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■94833 / inTopicNo.1)  BigEndianでデータを読み込む方法
  
□投稿者/ ひとひと (1回)-(2020/05/23(Sat) 20:13:12)

分類:[.NET 全般] 

BigEndianで書かれたバイナリデータをVB.NETを使って読み込みたいのですが、


    <Extension()>
    Private Function ReadInt16_BigEndian(reader As BinaryReader) As Short

        Dim DataNumByte() As Byte = reader.ReadBytes(2)

        Array.Reverse(DataNumByte)

        Return BitConverter.ToInt16(DataNumByte, 0)

    End Function

というようなルーチンを使うしかないですか?

自前で読み込めるようなコードで用意されていないのでしょうか?


引用返信 編集キー/
■94834 / inTopicNo.2)  Re[1]: BigEndianでデータを読み込む方法
□投稿者/ WebSurfer (2061回)-(2020/05/23(Sat) 20:43:50)
No94833 (ひとひと さん) に返信

> BigEndianで書かれたバイナリデータをVB.NETを使って読み込みたいのですが、

Stream として取得できるのなら StreamReader を使ってはいかがですか?
引用返信 編集キー/
■94836 / inTopicNo.3)  Re[2]: BigEndianでデータを読み込む方法
□投稿者/ Hongliang (1034回)-(2020/05/23(Sat) 20:53:15)
> Stream として取得できるのなら StreamReader を使ってはいかがですか?
バイナリデータなんだったらStreamReaderは意味がないのでは?

標準ではエンディアンを指定できるようなリーダやコンバータは用意されていませんね。
https://stackoverflow.com/questions/8620885/c-sharp-binary-reader-in-big-endian
こんな感じでBinaryReaderを継承したクラスをつくるぐらいでしょうか。
引用返信 編集キー/
■94837 / inTopicNo.4)  Re[3]: BigEndianでデータを読み込む方法
□投稿者/ WebSurfer (2062回)-(2020/05/23(Sat) 21:50:04)
No94836 (Hongliang さん) に返信
>>Stream として取得できるのなら StreamReader を使ってはいかがですか?
> バイナリデータなんだったらStreamReaderは意味がないのでは?

何故意味がないのですか? 理由は?
引用返信 編集キー/
■94839 / inTopicNo.5)  Re[3]: BigEndianでデータを読み込む方法
□投稿者/ WebSurfer (2063回)-(2020/05/23(Sat) 22:14:54)
No94836 (Hongliang さん) に返信

ちなみに、質問者さんが言うバイナリーデータとは UTF-16 BE とかであろうと
勝手に想像してます。
引用返信 編集キー/
■94840 / inTopicNo.6)  Re[4]: BigEndianでデータを読み込む方法
□投稿者/ Hongliang (1035回)-(2020/05/23(Sat) 22:19:17)
> 何故意味がないのですか? 理由は?
一般的には、バイナリはテキストに対置される用語で(例:FTPのバイナリモードとテキストモード)、StreamReaderはテキストを読み取るためのクラスだからですね。
引用返信 編集キー/
■94841 / inTopicNo.7)  Re[4]: BigEndianでデータを読み込む方法
□投稿者/ ひとひと (3回)-(2020/05/23(Sat) 22:47:54)
そうでしたか、やはいないんのですね・・・・

需要があるはずなので、
標準で用意してくれても良いと思ったのですが・・・

解決済み
引用返信 編集キー/
■94842 / inTopicNo.8)  Re[5]: BigEndianでデータを読み込む方法
□投稿者/ 魔界の仮面弁士 (2725回)-(2020/05/23(Sat) 23:40:59)
No94841 (ひとひと さん) に返信
> そうでしたか、やはいないんのですね・・・・

Int16 , Int32 , Int64 限定であれば、
 Return System.Net.IPAddress.HostToNetworkOrder(reader.ReadInt16())
と書くことはできます。
https://docs.microsoft.com/ja-jp/dotnet/api/system.bitconverter.islittleendian?view=netframework-4.8

このメソッドは組となるよう
 IPAddress.NetworkToHostOrder()
 IPAddress.HostToNetworkOrder()
というメソッドが用意されています。

これが IPAddress クラスに実装されているのは、TCP/IP プロトコルにおいて、
IP アドレスやポート番号などが「ビッグエンディアン」で格納することになっているためでしょう。
逆変換まで別メソッドにする必要があったのかは疑問ですが。

また、実行環境のエンディアンを調べるための、
BitConverter.IsLittleEndian フィールドも用意されています。


> Return BitConverter.ToInt16(DataNumByte, 0)

そして ToInt16 メソッドは、上記の IsLittleEndian に対応することを想定した実装になっているようです。
https://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs,64128518fca2c03f,references

>> fixed( byte * pbyte = &value[startIndex]) {
>>  if( startIndex % 2 == 0) { // data is aligned
>>   return *((short *) pbyte);
>>  }
>>  else {
>>   if( IsLittleEndian) {
>>    return (short)((*pbyte) | (*(pbyte + 1) << 8)) ;
>>   }
>>   else {
>>    return (short)((*pbyte << 8) | (*(pbyte + 1)));
>>   }
>>  }
>> }


IsLittleEndian フィールドは readonly です。
.NET Framework のソースコードをみると、値が静的に埋め込まれていますが、
他の互換フレームワーク…たとえば Mono においては
実行時に判定が行われる実装になっているようですね。

https://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs,34
https://github.com/mono/mono/blob/master/mcs/class/corlib/System/BitConverter.cs
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ