バイト配列自体が通常のプログラムではあまり使用しませんが、テキストファイルのデータをバイト型の配列に読み込んだり、制御関連のプログラムを作成する場合には、バイト配列を使用することもあるかと思います。
バイト配列とは、要素がバイト(byte)型の配列です。
byte型はC#のプリミティブ型の1つで、-128~127(10000000~01111111)までの範囲の値を取ることができます。
バイト型はバイナリデータを扱う際などに使用します。
バイト型のデータは文字列に変換することも可能で、バイト型配列のデータを文字列に変換する方法が.NET Frameworkには標準で用意されています。
そこで今回は、バイト型の配列(byte[])を文字列(string)に変換する方法について紹介します。
目次
System.Text.Encoding.GetString
バイト配列を文字列に変換するには、System.Text名前空間にあるEncodingクラスのGetStringメソッドを使用します。
GetStringメソッドのシグネチャ次のようになります。
1 |
public virtual string GetString (byte[] bytes); |
GetStringメソッドは引数(パラメーター)にバイト型の配列(byte[])を指定することで、文字列に変換して返してくれます。
System.Text.Encoding.GetChars
文字列に変換する処理は、GetStringメソッドを同じ名前空間のSystem.TextにあるGetCharsメソッドを使用することもできます。
GetCharsメソッドは引数に結果の文字のセットを格納する文字の配列(char[])を渡すことで、文字配列を格納してくれます。
GetCharsメソッドのシグネチャ次のようになります。
1 |
public abstract int GetChars (byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex); |
GetCharsメソッドの引数(パラメーター)はいくつかありますが
- 第1引数にはデコード対象のバイト シーケンスが格納されたバイト配列
- 第2引数にはデコードする最初のバイトのインデックス
- 第3引数にはデコードするバイト数
- 第4引数には結果の文字のセットを格納する文字配列
- 第5引数には結果の文字のセットを書き込む開始位置のインデックス
を指定します。
バイト型配列を文字列に変換するサンプル
以下にEncodingクラスのGetStringメソッドとGetCharsメソッドを使用して、ファイルからテキストを読み込んで画面に表示するサンプルプログラムを示します。
ここでは、簡単なWindowsフォームアプリケーションを作成し、画面で指定されたファイルパスをもとにファイルからデータをバイト配列に読み込み、それを文字列(String)に変換して画面に表示します。
フォームデザイン(画面構成)
フォームには、ファイルのパスを入力するテキストボックス(textBox1)と、ファイルからバイト配列にデータを読み込んで文字列に変換するボタン(button1)と、変換した文字列を表示するためのテキストボックス(textBox2)を配置しています。
(文字列の変換結果を表示するテキストボックスは、Multilineプロパティをtrueに設定して、複数行の文字列を表示できるようにしています。)
ソースコード(Form1)
フォームのソースコードは次にようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
using System; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent();textBox1.Multiline = true; } // ------------------------------------------------------------------------------------------------- // 読み込みボタンクリックイベント private void button1_Click(object sender, EventArgs e) { // テキストボックスからファイルパスを取得 string filePath = textBox1.Text; // ファイルパスが正しくない場合は終了 if (!System.IO.File.Exists(filePath)) { MessageBox.Show(filePath + " is not exists."); return; } // ファイル読み込み実行 string contents = Read(filePath); textBox2.Text = contents; } // 最大バッファサイズ private const int MaximumBufferSize = 2048; // UTF-8エンコーディング private static System.Text.Encoding utf8Encoding = System.Text.Encoding.UTF8; // ------------------------------------------------------------------------------------------------- // ファイル読み込み実行 public string Read(string filePath) { System.IO.FileStream fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open); string contents = null; // ファイルサイズが最大バッファサイズを超えている場合は1回で読み込む if (fileStream.Length <= MaximumBufferSize) { byte[] bytes = new byte[fileStream.Length]; fileStream.Read(bytes, 0, bytes.Length); // ※ GetStringメソッドで文字列を取得 contents = utf8Encoding.GetString(bytes); } // ファイルサイズが最大バッファサイズを超えている場合は複数回に分けて読み込む else { // バッファから読み込む contents = ReadFromBuffer(fileStream); } fileStream.Close(); // 読み込んだ内容を返す return contents; } // ------------------------------------------------------------------------------------------------- // バッファから読み込む private static string ReadFromBuffer(System.IO.FileStream fileStream) { // 最大バッファサイズのバイト配列 byte[] bytes = new byte[MaximumBufferSize]; // 出力する文字列 string output = string.Empty; // UTF-8エンコーディングのデコーダー System.Text.Decoder decoder8 = utf8Encoding.GetDecoder(); // 複数回読み込む while (fileStream.Position < fileStream.Length) { // ストリームからバイトのブロックを読み取り、そのデータを特定のバッファーに書き込む int byteCount = fileStream.Read(bytes, 0, bytes.Length); // デコードすることによって生成される文字数を取得 int charCount = decoder8.GetCharCount(bytes, 0, byteCount); char[] chars = new char[charCount]; // ※ GetCharsメソッド文字の配列を取得 charCount = decoder8.GetChars(bytes, 0, byteCount, chars, 0); // 出力する文字列に書き込む output += new string(chars, 0, charCount); } // 読み込んだ値(出力する文字列)を返す return output; } } } |
上記のサンプルプログラムでは、フォームに配置したボタンがクリックされた時のイベント処理でReadメソッドを呼び出して処理をしています。(41行目)
Readメソッドでは、ファイルパスのテキストボックスに入力された値(ファイルのパス)をもとに、System.IO名前空間にあるFileStreamクラスを使用してデータを読み込んでいます。
ファイルのサイズが小さい場合は1回で読み込みますが、大きい場合は複数回に分けて読み込んでいます。
ファイルを複数回に分けて読み込む処理はReadFromBufferというメソッドを作成して呼び出しています。(70行目)
1回で読み込める場合は、GetStringメソッドを使用して文字列に変換しています。
複数回に分けて読み込む場合は、GetCharsメソッドを使用して文字の配列を取得し、配列をもとに文字列(string)のインスタンス(オブジェクト)を生成しています。
サンプルプログラムの実行結果
サンプルプログラムを実行します。
読み込むテキストファイルには、以下のデータが入力されているものとします。
バイト配列を文字列に変換するサンプルで使用するテキスト
■■■■■■■■■■■■■■■■■■■■■■■■
GetStringメソッドとGetCharsメソッドを使用すると
バイト型の配列を文字列型に変換することができます。
■■■■■■■■■■■■■■■■■■■■■■■■
ファイルパスを入力して、「読み込み」ボタンをクリックして実行します。
実行するとテキストファイルの値を読み込んで、、複数行のテキストボックスに文字列が表示されることが確認できます。
バイト型の配列を文字列型に変換する際の注意点
バイト配列を文字列に変換する際に注意する点があります。
バイト型の配列から文字列型に変換する際には文字のエンコーディングを合わせる必要があります。
上記の例(サンプルプログラム)では、テキストファイルのデータをバイト配列に読み込んで文字列に変換する際にUTF-8エンコーディングを使用していますが、データを読み込むファイルのエンコーディングがUTF-8でなければ、正しく文字列に変換することができません。
C#(.NET Framework)での文字列(string)はUnicode(UTF-8)で扱われますが、Windowsで動作するテキストエディターでは、デフォルトがShift-JISになっている場合も多くあります。
上記のサンプルプログラムを動作させる際には、テキストファイルのエンコーディングをUTF-8にしないと正しく文字列に変換するころができません。
テキストファイルのエンコーディングが違う場合は、読み込むテキストファイルのエンコードに合わせたオブジェクトを用意する必要があります。
以下に代表的なエンコーディングのオブジェクトを作成する例をいくつか示しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Shift-JIS var sjisEncoding = System.Text.Encoding.GetEncoding("shift_jis"); // EUC var eucEncoding = System.Text.Encoding..GetEncoding("euc-jp"); // ASCII var asciiEncoding = System.Text.Encoding.ASCII; // Unicode var unicodeEncoding = System.Text.Encoding.Unicode; // UTF-8 var Encoding = System.Text.Encoding.UTF8; |
文字のエンコーディングの種類については、以下の記事も合わせてご覧ください。