2016年6月29日水曜日

[C#] ファイルシステム(File System) - FileStream、 Encoding、 Serializable

こんにちは。明月です。
前の投稿でファイルとディレクトリを扱う方法について勉強しました。今日はファイルを作成する方法について勉強します。


パソコンの中でファイルの種類は様々なことがあります。その中でドキュメントタイプだけで考えてもエクセル、ワード、テキスト、CSV等の様々な種類があります。
でもドキュメントタイプか、イメージ、様々なデータでもファイルは基本的にバイナリデータでされています。バイナリデータということをプログラム的に考えると「byte」タイプにされていることの意味です。


FileStream


C#にはその「byte」型にされているファイルを書き込むあるいは読み込むクラスがあり、それをC#では「FileStream」というクラスがバイナリを扱うことです。そうすると「FileStream」についてMSDNから調べ、使用方法について勉強します。


MSDNリンク - FileStream クラス



FileStreamはMSDNをみると「ファイルについてストリーム(Stream)を提供します」ということで書いています。
そうすると、Streamについて知らないので、まずFileStreamを勉強する前にStreamについて勉強します。「Stream」というのはファイルだけではなく通信と様々なデータを扱う時にStream(ストリーム)を使います。
我々がテキストを開いて文字を書いて格納するものまたは格納したファイルを開いて格納したデータを画面に確認するものだと思います。改めていうとデータを格納して格納したとおりに画面に見えることが当たり前だと思いますがパソコンの中では当たり前ではないですね。
テキストに「あいうえお」と書くとファイルが小さいからそのままで格納することができると思いますが、ファイルサイズが「100Mb」「1Gb」だとそのくらいの空間がハードディスクにない可能性もあります。



そして上の状況になるとデータを「20Mb」「50Mb」で分けてデータをハードディスクに格納します。でもユーザーが「File」を作成する時あるいは閲覧する時にファイルが分散されているものを探して合せることやファイルを作成する時にディスクをの空間を計算して分割するんだと思えばファイルシステムを実装することが結構難しくなると思われます。
それで「Stream」では格納する時に一連のデータを受け取ってディスクの状況に合わせてファイルを作成することやファイルが分散されているものを一連のデータに組み合わせて返却するデータを返却するデータ構造パターンです。


そうすると「FileStream」を利用して「byte」単位のデータをファイルに作成してみます。




上の例を見るとbyte変数にASCIIコードと合わせるデータを入れてファイルに出力しました。ただ、StringとInt系を入れなくてbyte型に入れることにはパソコンはデータを文字ままで認識することではなく2陣データの形式で認識するので、Byteタイプに変換する必要があります。byte形式の中でもUnicode、Shift-JIS等があり、例はACSIIコードを利用してファイルを作成しました。



そうすればファイルを作成するたびにデータをByte形式に変換しなければならないと思いますが、C#にはデータをbyte形式に変換するクラスを提供しています。


Encoding


Encodingクラスはデータをbyte形式に変換するクラスです。そしてEncodingクラスはバイナリコードのタイプのASCII、ユニコード、shift-jisを選択して変換することもできます。


MSDNリンク - Encoding クラス





上の例を見ると確かに「String」型のデータをユニコードのbyte形式に変換してファイルを作成しています。作成したファイルをメモ帳で開くと「String」式で格納したデータがメモ帳で表示されることを確認できます。


Serializable(直列化)


今回はデータ単位の変換ではなく、クラス単位のデータを「byte」型に変換することです。「C#」はクラスを「byte」に変換するためには「Serialize(直列化)」が必要です。
「C#」のdata形式は静的な構造体ではなくクラスタイプなのでデータの順番が無くポイント形式でされています。でも「File」のバイナリの構造に変換するには「Stream」のデータ順番が必要だし構造的なデータ形式にされなければならないと思います。
そんなことでクラス形式のデータを「Stream」式のデータ構造に変換することをSerializable(直列化)だといいます。


MSDNリンク - SerializableAttribute クラス



MSDNリンク - BinaryFormatter クラス



筆者は「serializable」と「BinaryFormatter」のことを紹介していますが、「C#」にはクラスを宣言することにクラスが「serializable」が可能かどうかを宣言して実際に「Stream」のデータ構造に変換する時には「BinaryFormatter」のクラスを利用してクラスデータをStream形式に変換しています。




上の例をみると「DataNode」クラスを10個割り当てリストに格納しています。そしてリスト自体を「BinaryFormatter」クラスを利用して「Stream」形式に変換し、ファイルに出力する例になります。出力したファイルをメモ帳に開くと人間が認識できない形でデータが作成されたことを確認できます。




今回は「serializable」して格納されたファイルを「BinaryFormatter」を利用して読み込んでクラスに割り当てしました。メモ帳には人間が認識できなかったデータでしだが、C#には「DataNode 」クラスデータが10個あるリストのデータで認識して読み込まれました。


今までファイルを作成することや読み込む方法について勉強しました。プロジェクトでプログラムを作る時にファイルの関連モジュールはたくさんあると思われます。なのでファイルシステムは重要な部分だと思いますね。少なくても プログラムのLogを作成する部分でファイルの入出力(IO)を使うと思います。そのことでプログラムを作成することではファイルの入出力は基本だと思うので、機能にとしてよく認知して勉強するほうが良いと思います。

0 件のコメント