いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

ADO.NET入門記-028 (テキストファイルに接続してデータを取得・追加)(text,OleDb,HDR,Extended Properties,FMT,Delimited)


前回に引き続き、変わり種で今度はテキストファイルに接続してみます。
要領としては、Excelに接続する場合とほぼ同じです。


利用するプロバイダーは以下のものとなります。

System.Data.OleDb


接続文字列は以下のようなパターンをとります。

Provider=Microsoft.ACE.OLEDB.12.0;Data Source={ファイルが存在するディレクトリ};Extended Properties="text;HDR={YES/NO};FMT=Delimited";

ISAMドライバには、textを指定します。
HDRは前回と同じく先頭行をヘッダとして扱うか否かの設定です。
後、FMT=Delimitedという記述も必要です。


注意点として、Data Sourceにはファイルパスを指定するのではなくて
ファイルが存在するディレクトリを指定します。では実際のファイル名は
どこで指定するのかといいますと、クエリで指定します。

SELECT * FROM [Persons.txt];


これで完了と言いたいところですが、このままではファイルの構造が分からない為
読み込む事が出来ません。


で、ファイルの構造を記述した特殊なファイルを作成する必要があります。
ファイル名は

schema.ini

で固定です。これをファイルと同じディレクトリ内に設置します。
この中にこのファイルの構造を記述します。


今回のサンプルデータファイルです。

ID,NAME,AGE
1,gsf_zero1,30
2,gsf_zero2,31
3,gsf_zero3,32
4,gsf_zero4,33
5,gsf_zero5,34
6,gsf_zero6,35

これをPersons.txtとして保存しておきます。


上記のファイルの構造を記述したschema.iniファイルです。

[Persons.txt]
Format=CSVDelimited
ColNameHeader=True
MaxScanRow=0
Charactor=OEM
Col1=ID Long Width 2
Col2=Name Text Width 20
Col3=AGE Long Width 2

セクションにはファイル名を設定します。
残りのキーは以下のような値を設定します。

キー 説明
Format CSVDelimited, Delimited(区切り文字), FixedLength, TabDelimitedを指定
ColNameHeader 先頭行をヘッダとするか否か
MaxScanRow 列のデータ型判別に利用する行数(0は全行を表す)
Charactor ANSI or OEM
ColN 列の定義 (書式:列名 型 Width 長さ)


列の定義に利用できる型は以下のものとなります。

  • Bit
  • Byte
  • Currency
  • DateTime
  • Double
  • Long
  • Memo
  • Short
  • Single
  • Text

以下、サンプルです。

#region TextConnectSamples-01
    public class TextConnectSamples01 : IExecutable {

        public void Execute() {
            //
            // OleDbプロバイダを利用してテキストファイル(CSV)に接続する.
            //
            DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OleDb");
            using(DbConnection conn = factory.CreateConnection()) {
                //
                // テキストファイルに接続する為の接続文字列を構築.
                //
                // 基本的にExcelに接続する場合とほぼ同じ要領となる。
                // Extended Properties内のISAMドライバがExcel 12.0からtextになる。
                // また、フォーマット方式を指定する必要がある。
                //
                // Data Sourceに指定するのは、該当ファイルが存在するディレクトリを指定する。
                // 尚、該当ファイルの構造については別途schema.iniファイルを同じディレクトリに
                // 用意する必要がある。
                //
                DbConnectionStringBuilder builder = factory.CreateConnectionStringBuilder();

                builder["Provider"]            = "Microsoft.ACE.OLEDB.12.0";
                builder["Data Source"]         = @".";
                builder["Extended Properties"] = "text;HDR=YES;FMT=Delimited";

                conn.ConnectionString = builder.ToString();
                conn.Open();

                //
                // SELECT.
                // FROM句の中に読み込む対象のファイル名を指定する。
                // データが取得される際にschema.iniファイルが参照され、列定義が行われる。
                //
                using(DbCommand command = conn.CreateCommand()) {

                    command.CommandText = "SELECT * FROM [Persons.txt]";

                    DataTable table = new DataTable();
                    using(DbDataReader reader = command.ExecuteReader()) {
                        table.Load(reader);
                    }

                    foreach(DataRow row in table.Rows) {
                        Console.WriteLine("{0},{1},{2}", row["ID"], row["NAME"], row["AGE"]);
                    }
                }

                //
                // INSERT.
                // Accessの場合と同じくテキストファイルは追加・参照しか出来ない。
                // (つまり、更新・削除は出来ない)
                //
                using(DbCommand command = conn.CreateCommand()) {

                    string query = string.Empty;

                    query += " INSERT INTO [Persons.txt] ";
                    query += "     (ID, NAME, AGE) ";
                    query += "     VALUES ";
                    query += "     (7, 'gsf_zero7', 37) ";

                    command.CommandText = query;
                    command.ExecuteNonQuery();

                    using(DbCommand command2 = conn.CreateCommand()) {

                        command2.CommandText = "SELECT * FROM [Persons.txt]";

                        DataTable table = new DataTable();
                        using(DbDataReader reader = command2.ExecuteReader()) {
                            table.Load(reader);
                        }

                        foreach(DataRow row in table.Rows) {
                            Console.WriteLine("{0},{1},{2}", row["ID"], row["NAME"], row["AGE"]);
                        }
                    }
                }

                //
                // UPDATE
                // この ISAM では、リンク テーブル内のデータを更新することはできません。
                //

                //
                // DELETE.
                // この ISAM では、リンク テーブル内のデータを削除することはできません。
                //
            }
        }
    }
#endregion


尚、ソースにもコメントとして記述してますが更新・削除処理は行えません。