■ バイナリ を扱うメソッド
バイナリファイル の扱い
* FileStreamクラスを利用する
例
var buffer = new byte[fileStream.Length]; fileStream.Read(buffer, 0, buffer.Length);
https://docs.microsoft.com/ja-jp/dotnet/api/system.io.filestream.read?view=netframework-4.8
Byte[]の扱い
* 以下の関連記事を参照のこと
https://blogs.yahoo.co.jp/dk521123/38080788.html
■ サンプル
例1
// 日本語未対応。半角英数字のみ using System; using System.IO; using System.Text; using System.Windows.Forms; namespace SampleForm { public partial class Form1 : Form { private const string FilePath = "BinaryFile.bin"; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { var textData = this.textBox1.Text; var binary = Encoding.ASCII.GetBytes(textData); this.WriteBinaryFile(binary, FilePath); this.textBox1.Text = "Done to Write"; } private void button2_Click(object sender, EventArgs e) { var binary = this.ReadBinaryFile(FilePath); var textData = Encoding.ASCII.GetString(binary); this.textBox1.Text = textData; } public void WriteBinaryFile(byte[] targets, string filePath) { using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { fileStream.Write(targets, 0, targets.Length); } } public byte[] ReadBinaryFile(string filePath) { using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { var buffer = new byte[fileStream.Length]; fileStream.Read(buffer, 0, buffer.Length); return buffer; } } } }
例2:衛星データ(※1)
using System; using System.IO; using System.Text; using System.Windows.Forms; namespace SampleForm { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { var textData = this.ExtractBinaryData(@"0000008659_001001_ALOS2014410740-140829\LED-ALOS2014410740-140829-UBSL1.5GUA"); this.textBox1.Text = textData; } public string ExtractBinaryData(string filePath) { var binary = ReadBinaryFile(filePath); StringBuilder returnValue = new StringBuilder(); int offset; int start; int length; // offset = 1606052(1881A4) offset = // ファイルディスクリプタ 720 + // データセットサマリ 4096 + // 地図投影データ(L1.5/3.1 のみ) 1620 + // プラットフォーム位置データ 4680 + // 姿勢データ 16384 + // ラジオメトリックデータ 9860 + // データ品質サマリ 1620 + // 設備関連データ1(ダミー) 325000 + // 設備関連データ2(確定軌道暦) 511000 + // 設備関連データ3(時刻誤差情報) 3072 + // 設備関連データ4(座標変換情報) 728000; start = 0; length = 4; returnValue.AppendLine( string.Format("レコード順序番号 : {0}", this.ToInt32(binary, offset, start, length))); offset = offset + length; start = start + length; length = 1; returnValue.AppendLine( string.Format("第1レコードサブタイプコード : {0}", this.ToByte(binary, offset, start, length))); offset = offset + length; start = start + length; length = 1; returnValue.AppendLine( string.Format("レコードタイプコード : {0}", this.ToByte(binary, offset, start, length))); offset = offset + length; start = start + length; length = 1; returnValue.AppendLine( string.Format("第2レコードサブタイプコード : {0}", this.ToByte(binary, offset, start, length))); offset = offset + length; start = start + length; length = 1; returnValue.AppendLine( string.Format("第3レコードサブタイプコード : {0}", this.ToByte(binary, offset, start, length))); offset = offset + length; start = start + length; length = 4; returnValue.AppendLine( string.Format("レコード長 : {0}", this.ToInt32(binary, offset, start, length))); offset = offset + length; start = start + length; length = 4; returnValue.AppendLine(string.Format("設備関連データレコード番号('bbb5' bは半角SP) : {0}", this.ToASCII(binary, offset, start, length))); offset = offset + length; start = start + length; length = 20; returnValue.AppendLine(string.Format("係数1( -8.7033552055E+06) : {0}", this.ToDouble(binary, offset, start, length))); offset = offset + length; start = start + length; length = 20; returnValue.AppendLine(string.Format("係数2( 1.9225834432E+05) : {0}", this.ToDouble(binary, offset, start, length))); returnValue.AppendLine("後は省略"); return returnValue.ToString(); } public byte[] ReadBinaryFile(string filePath) { using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var buffer = new byte[fileStream.Length]; fileStream.Read(buffer, 0, buffer.Length); return buffer; } } private void button2_Click(object sender, EventArgs e) { byte[] bytes = { 0x00, 0x00, 0x00, 0x0C }; // If the system architecture is little-endian (that is, little end first), // reverse the byte array. if (BitConverter.IsLittleEndian) { Array.Reverse(bytes); } int value = BitConverter.ToInt32(bytes, 0); this.textBox1.Text = string.Format("int: {0}", value); } private double ToDouble(byte[] bytes, int offset, int start, int length) { var value = this.ToASCII(bytes, offset, start, length); return Double.Parse(value); } private int ToInt32(byte[] bytes, int offset, int start, int length) { byte[] targetInBytes = new byte[length]; Array.Copy(bytes, offset, targetInBytes, 0, length); if (BitConverter.IsLittleEndian) { Array.Reverse(targetInBytes); } return BitConverter.ToInt32(targetInBytes, 0); } private byte ToByte(byte[] bytes, int offset, int start, int length) { byte[] targetInBytes = new byte[length]; Array.Copy(bytes, offset, targetInBytes, 0, length); if (BitConverter.IsLittleEndian) { Array.Reverse(targetInBytes); } return targetInBytes[0]; } private string ToASCII(byte[] bytes, int offset, int start, int length) { byte[] targetInBytes = new byte[length]; Array.Copy(bytes, offset, targetInBytes, 0, length); return Encoding.ASCII.GetString(targetInBytes); } } }
※1 補足:衛星データ について
サンプルデータ
https://www.eorc.jaxa.jp/ALOS-2/doc/sam_jindex.htm
の「2014年8月29日 東京 高分解能3mモード (HH偏波) / L1.5 CEOS (zip圧縮ファイル / 1.79 GB)」を使用する * CEOS(Comittee on Earth Obsevation Satellites)については、以下のサイト参照
http://rs.aoyaman.com/seminar/about3.html
フォーマット
https://www.eorc.jaxa.jp/ALOS-2/doc/jformat.htm
より抜粋。(上の「■ サンプル」で使用しているのは、「SAR リーダ」になる)
表 3.1-1 CEOS レベル1.1/1.5/3.1 ファイル命名規約 (P40) より一部抜粋
ファイル種別 | ファイル名称規約 | ファイル数 | 内容 |
---|---|---|---|
ボリュームディレクトリ | VOL-シーンID-プロダクトID | 1 | ファイルの先頭に位置し、当該ボリューム及びファイルの管理情報を格納する |
SAR リーダ | LED-シーンID-プロダクトID | 1 | イメージファイルの前に位置し、後続するファイルの内の画像データと関連のあるアノーテーションデータ、アンシラリデータ等の情報を格納する |
SAR | イメージ(広域観測モードかつレベル1.1の場合) | IMG-偏波情報-シーン ID-プロダクトID-スキャン情報 | n(偏波数×スキャン数)|リーダファイルの次に位置し、画像データを格納する |
SARイメージ(上記以外の場合) | IMG-偏波情報-シーンID-プロダクトID | n(偏波数) | リーダファイルの次に位置し、画像データを格納する。 |
SARトレイラ | TRL-シーンID-プロダクトID | 1 | イメージファイルの次に位置し、画像データに関する最終情報を格納する |
表 3.2-1 CEOS レベル1.1/1.5/3.1 フォーマットレコード構成 (P46) より一部抜粋
レコード長[byte] | レコード数 | レコード名 |
---|---|---|
720 | 1 | ファイルディスクリプタ |
4096 | 1 | データセットサマリ |
1620 | 1 | 地図投影データ(L1.5/3.1 のみ) |
4680 | 1 | プラットフォーム位置データ |
16384 | 1 | 姿勢データ |
9860 | 1 | ラジオメトリックデータ |
1620 | 1 | データ品質サマリ |
325000 | 1 | 設備関連データ1(ダミー) |
511000 | 1 | 設備関連データ2(確定軌道暦) |
3072 | 1 | 設備関連データ3(時刻誤差情報) |
728000 | 1 | 設備関連データ4(座標変換情報) |
5000 | 1 | 設備関連データ5(緯度経度変換係数) |
3.3. プロダクトフォーマット (P35) より一部抜粋
表 3.3-1~表 3.3-17 に各レコードのフォーマットを示す。 尚、表中において「b」は半角空白文字を表している。 また、「数字)10」は、数字が10 進数で表されていることを示している。 表 3.3-18 にCEOS レベル1.1/1.5/3.1 フォーマットに記述されている項目に対する定義を示す。 また表3.3-19~表3.3-27 にアンテナビーム番号とパラメータを示す。
表 3.2-2 データタイプ一覧 (P79) より一部抜粋
タイプ(略号) | 詳細 |
---|---|
Im | 整数を表現するASCII 文字列(右詰め) |
Em.n | 実数タイプデータ表示(指数表現、右詰め) |
Bm | 2 進数表示(1 番目が最上位のバイト、ビッグエンディアン) |
m:表示桁数 n:小数点以下の桁数 p:指数における乗数
表 3.3-12 設備関連レコード5(1/4) (P79) より一部抜粋
フィールドNo. | バイトNo. | タイプ | 記述(定義と値) |
---|---|---|---|
1 | 1 - 4 | B4 | レコード順序番号。レベル1.5/3.1の場合 = 12)10 |
2 | 5 - 5 | B1 | 第1レコードサブタイプコード = 18)10 |
3 | 6 - 6 | B1 | レコードタイプコード = 200)10 |
4 | 7 - 7 | B1 | 第2レコードサブタイプコード = 18)10 |
5 | 8 - 8 | B1 | 第3レコードサブタイプコード = 70)10 |
6 | 9 - 12 | B4 | レコード長 = 5000)10 |
7 | 13 - 16 I4 | 設備関連データレコード番号 = 'bbb5' | |
8 | 17 - 416 | 20E20.10 | 緯度、経度をライン、ピクセルに変換する20の係数 |
参考文献
http://www.atmarkit.co.jp/ait/articles/0711/08/news120.html
https://dobon.net/vb/dotnet/file/filestream.html
https://qiita.com/ajillo/items/b61b2d05bbd4180650be
https://www.ipentec.com/document/csharp-filestream-read-write-binary