カテゴリー
C#

[C#]タブ区切り(TSV)のファイルを項目単位に読み取る

C#でタブ区切りのファイルを開き、1項目ずつ読み取る方法を紹介します。

//区切り文字設定
char[] delimiter = new char[] { '\t' };

//ファイルストリームリーダー作成
// InputFilePath にはタブ区切りファイルのパスを指定して下さい。
StreamReader reader = new StreamReader(InputFilePath);

//ファイルレコードが存在するまでループ
while (reader.Peek() >= 0)
{
    //読み取った行をタブで区切り、文字列配列に格納
    string[] cols = reader.ReadLine().Split(delimiter);

    //項目値取得
    col1value = cols[0];
    col2value = cols[1];
    col3value = cols[2];
}

1. 区切り文字の指定

今回の区切り文字であるタブを指定します。

char[] delimiter = new char[] { '\t' };

2. ファイルリーダーの作成

ファイルリーダーを作成します。InputFilePathには、読み込むタブ区切りのファイルパスを指定して下さい。

StreamReader reader = new StreamReader(InputFilePath);

3. ファイルレコードが存在するまでループ

while (reader.Peek() >= 0)
{
 ...
}

4. ファイルを1行読み取って、指定した区切り文字で分割して、文字列配列に格納

string[] cols = reader.ReadLine().Split(delimiter);

5. 各項目の値を取得

    col1value = cols[0];
    col2value = cols[1];
    col3value = cols[2];
カテゴリー
C#

[C#]コピー先にディレクトリが存在しない場合、作成してコピーする方法

C# でファイルをコピーする際に、コピー先のディレクトリが存在しない場合はエラーになります。

ファイルコピーする前にディレクトリ存在チェックを行い、存在しない場合は作成してからファイルコピーする関数を作成しましたので、紹介します。

        static void CreateDirAndCopyFile(string sourceFullPath, string distFullPath)
        {
            string distDir = Path.GetDirectoryName(distFullPath);
            if(!Directory.Exists(distDir)){
                Directory.CreateDirectory(distDir);
            }

            File.Copy(sourceFullPath, distFullPath, true);
        }

1. 引数は「コピー元のファイルフルパス」と「コピー先のファイルフルパス」

普通のコピーコマンドと同じような引数構成にしています。戻り値はありませんので、必要であればカスタマイズしてみてください。

2. コピ先ファイルフルパスから、ディレクトリパスを取得

フルパスからディレクトリパスを取得するには、以下の関数を使用します。

string distDir = Path.GetDirectoryName(distFullPath);

Path.GetDirectoryName 関数を使用します。戻り値にディレクトリパスが設定されます。

3. ディレクトリ存在チェック

ディレクトリ存在チェックを行うには、以下のように記述します。

Directory.Exists(distDir)

ディレクトリが存在する場合は「true」、存在しない場合は「false」が戻り値になります。

4. ディレクトリを作成する

ディレクトリを作成するには、以下のように記述します。

Directory.CreateDirectory(distDir)

Directory.CreateDirectory 関数にディレクトリパスを引数として設定すると、ディレクトリが作成できます。

5. ファイルをコピーする

File.Copy(sourceFullPath, distFullPath, true);

File.Copy 関数でファイルをコピーします。第三引数は、上書きするかどうかを指定します。Trueの場合、上書きします。

カテゴリー
ASP.NET aws C#

Aws lambda で asp.net core サーバーレスウェブアプリを構築する

AWS Lambda を使って、Nodejs の express でウェブページを表示することができますが、これと同じように、ASP.net Core を lambda で実行してウェブページを表示することができます。

まさにサーバーレスな Asp.Net Core です。EC2などの VPS は不要です。

開発・デプロイの方法を紹介します。

1. AWS Toolkit for Visual studio をインストールする

AWS ToolKit for Visual Studio とは、AWS の開発を容易にするvisual studio の拡張機能です。以下のURLからダウンロードできます。

https://aws.amazon.com/jp/visualstudio/

2. 新規プロジェクトからAWS serverless application を作成する

新規プロジェクト作成画面から「aws」でフィルタリングすると、awsに関するプロジェクトが表示されます。その中から「AWS Serverless Application」を選択します。

3. 発行に必要な権限を付与する

Lambda 関数の作成など、いろんなことを自動で処理してくれますので、AWS Console の IAM 画面から権限を付与します。

必要な権限をメモしてみましたが、必要に応じて権限を追加してください。

  • Lambda full access
  • IAM Full access
  • Amazon API Gateway Full Access
  • CloudFormation Full Access

Full Access にする必要は無いかもしれませんが、手っ取り早くするためにフルアクセスにしました。

4. AWS Lambda に発行する

ソリューションエクスプローラーの右クリックメニューから、「Publish to AWS Lambda」をクリックします。

プロファイルを選択し、Stack Name と S3 Bucket Name を選択し、右下の Publish ボタンをクリックします。

正常に作成処理が完了すると、この画面のようにlambda関数が作成されます。

5. ウェブページにアクセスしてみる

AWS Console からAPI Gateway にアクセスします。発行処理で作成されたAPI Gateway の左側メニューから、「Stage」を選択して表示されているURL をクリックします。

そうすると以下の画面が表示されるはずです。

まとめ

この手順で作成することで、サーバーレスなASP.NET Core ウェブページを作成することができます。VPS などの専用サーバーが不要になりますので、状況によっては安価に環境を構築することができます。

.NET CORE ユーザーにとってはウェブサイトを開発する選択肢のひとつとして考えて頂けるといいかと思います。

カテゴリー
C#

c# コマンドプロンプトのコマンドを実行するc#プログラムソース

C#からコマンドプロンプトのコマンドを実行するソースコードを紹介します。

    /// <summary>
    /// バッチコマンドを実行する
    /// </summary>
    /// <param name="executeCommand">コマンド文字列</param>
    /// <param name="stdOut">標準出力</param>
    /// <param name="stdErr">標準エラー出力</param>
    /// <param name="exitCode">終了コード</param>
    /// <returns>リターンコード</returns>
    public static int ExecBatProcess(string executeCommand, out string stdOut, out string stdErr, out int exitCode)
    {
        stdOut = "";
        stdErr = "";
        exitCode = 0;

        try
        {
            Process process = new Process();
            ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe", "/c " + executeCommand);
            processStartInfo.CreateNoWindow = true;
            processStartInfo.UseShellExecute = false;

            processStartInfo.RedirectStandardOutput = true;
            processStartInfo.RedirectStandardError = true;

            process = Process.Start(processStartInfo);
            process.WaitForExit();

            stdOut = process.StandardOutput.ReadToEnd();
            stdErr = process.StandardError.ReadToEnd();
            exitCode = process.ExitCode;

            process.Close();

            return 0;
        }
        catch
        {
            return 16;
        }
    }

引数

executedCommand
コマンドプロンプトで実行するコマンドと引数を指定します。バッチファイルパスでもOKです。

stdOut
標準出力の内容を返します。

stdErr
標準エラー出力の内容を返します。

exitCode
コマンド実行後のリターンコードを返します。

使用例

    public string batchStdOut;
    public string batchStdErr;
    public int batchExitCode = 0;

    string batPath = @"D:\uploads3.bat";
    UEProcess.ExecBatProcess(batPath, out batchStdOut, out batchStdErr, out batchExitCode);

batPath に指定したバッチファイルを実行し、標準出力、標準エラー出力、リターンコードを取得します。

カテゴリー
ASP.NET C#

ASP.NET CORE で Tweet 機能を構築する

ASP.NET CORE では razor 構文というものが使用できます。razor 構文を使用すると、クリック時のイベントロジックを実装したり、テキストに入力した値を取得することができるようになります。

この記事では、ASP.NET CORE で razor 構文を使用して、ツイート専用画面を構築する方法を紹介します。

1. ファイル構成とソース

今回は2つのファイルに分けて構築します。

1.1 Shared/TweetBox.razor

Sharedフォルダにrazor ファイルを作成することで、独自タグのように使用することができます。ソースコードは以下のようになります。

<h3>TweetBox</h3>

<textarea id="note" cols="10" style="width: 100%" @bind="@tweetText" placeholder="TweetText"></textarea>



<div>
    <a href="https://twitter.com/intent/tweet?text=+@(tweetText)">
        <img src="/Image/tweet.png" style="border-radius: 30%; border: 1px solid black;" width="100%" />
    </a>
</div>

@code {

    string tweetText;

}

上から3行目の textarea でツイート本文を記載します。

tweetText という string型の変数に textarea の入力内容をバインドしています。ちなみに、tweetText という変数は、@code ブロックの中で宣言しています。

実際のツイートロジックは、Twitter から提供されている Web Intent を使用します。Web Intent の詳細は以下のURLで説明されています。

https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/web-intent

1.2 Pages/Tweet.razor

Pages フォルダで実際のページを構成していきます。ソースコードは以下になります。

@page "/Tweet"

<TweetBox />

TweetBox というタグを使用して、さきほどのソースを呼び出しています。

2. 実行イメージ

こんな感じでツイートができます。

カテゴリー
C#

C# 指定された DSN には、ドライバーとアプリケーションとのアーキテクチャの不一致が含まれています。の対処方法

.Net Framework 3.5 で開発したアプリケーションを Windows 10 64 bit で
実行し、ODBC(32bit)でデータベースアクセスしようとしたときに発生しました。

原因としては、アプリケーションの実行が64bitであるにも関わらず、
ODBCが32bitのため、このエラーメッセージが発生しました。

・アプリケーション:64bit
・OS:64bit
・ODBCドライバ:32bit

こんな状態です。アプリケーションとODBCドライバのアーキテクチャ(bit数)を
一緒にする必要があるようです。

対策は、32bitアプリケーションとして実行するように、ビルドオプションを変更しました。

プラットフォームターゲットが
・Any CPU の場合、OSのアーキテクチャによって32bitや64bitに変更されます。
・x86 の場合、OSのアーキテクチャによらず、32bitで実行されます。
・x64 の場合、OSのアーキテクチャによらず、64bitで実行されます。

ちなみに、実行時のbit数が32bitか64bitかを取得するソースを紹介します。

    /// <summary>
    /// 実行時のアーキテクチャが32Bitか64Bitかを判断する
    /// </summary>
    /// <param name="processBit"></param>
    /// <returns></returns>
    public static int GetRunningArch(out string processBit)
    {
        processBit = "";

        try
        {
            if (IntPtr.Size == 4) processBit = "32bit";
            else processBit = "64bit";

            return UEReturnCode.Normal;
        }
        catch
        {
            return UEReturnCode.Error;
        }

    }
    
カテゴリー
aws C#

C# で簡単に AWS S3 にファイルをアップロードするソースコード

C# でAmazon AWS S3 に ファイルをアップロードする方法はいろいろありますが、シンプルに簡単にファイルをアップロードするソースコードを紹介します。

using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using System;

namespace autocbk
{
    class FAmazonS3
    {
        private static readonly Amazon.RegionEndpoint bucketRegionEndPoint = Amazon.RegionEndpoint.APNortheast1;
        private static IAmazonS3 s3Client;

        public static int UploadFile(string bucketName, string filePath)
        {
            try
            {
                s3Client = new AmazonS3Client(bucketRegionEndPoint);

                TransferUtility fileTransferUtility = new TransferUtility(s3Client);
                fileTransferUtility.Upload(filePath, bucketName);

                return 0;
            }
            catch(Exception e)
            {
                return 9;
            }
        }

    }
}

必要なNuGetパッケージ

AWSSDK.S3 が必要です。これをインストールすると、AWSSDK.Core が自動的についてきます。

aws s3 nuget package

ソースコード説明

  1. リージョンエンドポイントの指定
private static readonly Amazon.RegionEndpoint bucketRegionEndPoint = Amazon.RegionEndpoint.APNortheast1;

このコードで、リージョンを「APNothEast1」に指定します。

2. アップロード関数の定義

public static int UploadFile(string bucketName, string filePath)

この関数は、 bucketName と filePath を引数に持ち、int型でリターンコードを返却します。

3. S3にファイルをアップロード

fileTransferUtility.Upload(filePath, bucketName);

TransferUtility オブジェクトのUpload 関数でアップロードを行います。TransferUtility クラスの公式ドキュメントは以下にあります。

https://docs.aws.amazon.com/sdkfornet/latest/apidocs/items/TS3TransferTransferUtilityNET45.html

カテゴリー
C#

[C#]ODBC 接続したテーブルのレコード件数を取得する

ODBC で接続したデータベースのテーブルに対して、レコード件数を取得するメソッドを照会します。
このメソッドは、Where文の指定も可能です。

App.config に ODBC 接続文字列を設定する

<configuration>

  <connectionStrings>
    <add name="...DB名..."
         connectionString="...ODBC 接続文字列..."/>
  </connectionStrings>

</configuration>

<connectionStrings> で接続文字列を定義します。

<add> タグ の name でDB名を定義し、 connectionString で接続文字列を定義します。

C# GetODBCRecordCount メソッド

/// <summary>
/// ODBC経由でテーブルレコード件数を取得する
/// </summary>
/// <param name="DBName">ODBC接続文字列DB名称</param>
/// <param name="SqlFrom">テーブル名</param>
/// <param name="SqlWhere">Where文</param>
/// <returns>テーブルレコード件数(異常時:0)</returns>
public static int GetODBCRecordCount(string DBName, string SqlFrom, string SqlWhere)
{

    int recordCount = 0;

    try
    {

        //App.config のconnectionStrings から接続文字列を取得する
        string cnstr = ConfigurationManager.ConnectionStrings[DBName].ConnectionString;

        //ODBCConnection オブジェクトを生成して、オープンする
        OdbcConnection cn = new OdbcConnection(cnstr);
        cn.Open();

        //レコード件数カウントSQLを組み立てる
        string sqlstr = "";
        sqlstr = sqlstr + "SELECT  COUNT(*)  AS  CNT  FROM  " + SqlFrom;

        //引数に Where が設定されていれば、Where文を付与する
        if (SqlWhere != "")
        {
            sqlstr = sqlstr + "  WHERE  " + SqlWhere;
        }

        // ODBCコマンドをセットする
        OdbcCommand oc = new OdbcCommand(sqlstr, cn);

        // ODBCクエリを実行する
        OdbcDataReader odr = oc.ExecuteReader();

        // レコードが読込める間ループする
        while (odr.Read() == true)
        {
            //レコード件数を取得し、Int32型に変換する
            recordCount = Convert.ToInt32(odr["CNT"]);
        }

        //クローズする
        odr.Close();
        cn.Close();

    }
    catch(Exception ex)
    {
        throw;
    }

    return recordCount;
}

引数

  • 引数に DBNmae, SqlFrom, SqlWhere を指定します。

  • DBName は、さきほど App.config に指定した接続文字列の DBName を指定します。

  • SqlFrom にテーブル名を指定します。 SQLのFROM文に相当します。

  • SqlWhere にWhere条件を指定します。SQLのWhere文に相当します。

件数カウントSQLの組み立て

このメソッドでは、以下のSQL文を組み立てます。

SELECT  COUNT(*)  AS  CNT  FROM  <SqlFrom:テーブル名>  WHERE  <SqlWhere:Where文>

接続文字列の取得

string cnstr = ConfigurationManager.ConnectionStrings[DBName].ConnectionString;

ConfigurationManager クラスを用いて、App.config に記入した接続文字列を取得します。

DB接続オープン

cn.Open();

OdbcCommand.Connection メソッドで接続をオープンします。

SQL文のセットと実行

// ODBCコマンドをセットする
OdbcCommand oc = new OdbcCommand(sqlstr, cn);

// ODBCクエリを実行する
OdbcDataReader odr = oc.ExecuteReader();

OdbcCommand に SQL文と接続情報(OdbcConnection)を指定します。

クエリの実行は、OdbcCOmmand.ExecuteReader()メソッドを使用し、OdbcDataReaderクラスにセットします。

レコードを取得する

// レコードが読込める間ループする
while (odr.Read() == true)
{
    //レコード件数を取得し、Int32型に変換する
    recordCount = Convert.ToInt32(odr["CNT"]);
}

レコード件数が終端に達するまでループします。

取得したレコードから レコード件数 CNT の値を取得します。この項目は Double型ですので、Int32型に変換します。

クローズ処理

odr.Close();
cn.Close();

OdbcDataReaderOdbcConnection をクローズします。

レコード件数の返却

return recordCount;

最後に、レコード件数を返却して終了します。

カテゴリー
C#

[C#]ODBCでデータベースに接続してテーブルを更新する

ODBCで接続したデータベースに対して、INSERT・UPDATE・DELETEなど、テーブルを更新する方法を紹介します。

App.config に ODBC 接続文字列を設定する

<configuration>

  <connectionStrings>
    <add name="...DB名..."
         connectionString="...ODBC 接続文字列..."/>
  </connectionStrings>

</configuration>

<connectionStrings> で接続文字列を定義します。

<add> タグ の name でDB名を定義し、 connectionString で接続文字列を定義します。

C# UpdateODBCDatabase メソッド

/// <summary>
/// ODBCデータベースのレコードを更新します。
/// </summary>
/// <param name="DBName">ODBC接続文字列DB名称</param>
/// <param name="sqlList">SQL文リスト(INSERT/UPDATE/DELETE)</param>
/// <returns>リターンコード(0:正常、9:異常)</returns>
public static int UpdateODBCDatabase(string DBName, List<string> sqlList)
{
    //App.config のconnectionStrings から接続文字列を取得する
    string cnstr = ConfigurationManager.ConnectionStrings[DBName].ConnectionString;

    // OdbcConnection クラスを使用
    using (OdbcConnection cn = new OdbcConnection(cnstr))
    {
        OdbcCommand command = new OdbcCommand();
        OdbcTransaction trans = null;

        command.Connection = cn;

        try
        {
            //DB接続オープン
            cn.Open();

            //トランザクションを開始
            trans = cn.BeginTransaction();

            //接続とトランザクション情報をセット
            command.Connection = cn;
            command.Transaction = trans;

            //List<String>型に格納しているSQLを foreach でループ
            sqlList.ForEach(delegate(String sqlstr)
            {
                //SQLを設定し、クエリを実行
                command.CommandText = sqlstr;
                command.ExecuteNonQuery();
            });

            //トランザクションをコミット
            trans.Commit();

        }
        catch(Exception ex)
        {
            //エラーが発生した場合はロールバック
            trans.Rollback();
            return 9;
        }

    }

    return 0;

}

引数

  • 引数に DBNamesqlList を指定します。

  • DBName は、さきほど App.config に指定した接続文字列の DBName を指定します。

  • sqlList は、List<string>型の変数で、INSERT文やUPDATE文などのSQLを指定します。

接続文字列の取得

string cnstr = ConfigurationManager.ConnectionStrings[DBName].ConnectionString;

ConfigurationManager クラスを用いて、App.config に記入した接続文字列を取得します。

DB接続オープン

cn.Open();

OdbcCommand.Connection メソッドで接続をオープンします。

トランザクションを開始

trans = cn.BeginTransaction();

OdbcCommand.Connection.BeginTransaction() メソッドで、トランザクションを開始します。

SQL を実行

//List<String>型に格納しているSQLを foreach でループ
sqlList.ForEach(delegate(String sqlstr)
{
    //SQLを設定し、クエリを実行
    command.CommandText = sqlstr;
    command.ExecuteNonQuery();
});

List<string> 型の変数 sqlListForEachメソッドで1行ずつ取得します。

その後、OdbcCommand.CommandText にSQL文をセットします。

OdbcCommand.ExecuteNonQuery メソッドでSQL文を実行します。

トランザクションをコミット

trans.Commit();

OdbcTransaction.Commit() メソッドでコミットを実行します。

カテゴリー
C#

C# で画像フォーマットを変換するプログラム

ブログを書いていて、png を jpg に変換していたのですが、1ファイルずつペイント開いてリサイズして
名前をつけて保存していくのが、かなりめんどくさくなりましたので、プログラムを書きました。

なんで C# なのか?

最初は Node.js でやりたかったので、NPM から png-to-jpeg
インストールして使ってみましたが、私が変換したい画像はうまくいきませんでした。

変換するソースコード

using System;
using System.Drawing;

namespace ImgConv
{
    class Program
    {
        static void Main(string[] args)
        {

            String fromFilePath = args[0];
            String toFilePath = args[1];

            Image orgImage = Image.FromFile(fromFilePath);
            orgImage.Save(toFilePath);

            orgImage.Dispose();
        }
    }
}

プログラム引数から、以下2つを取得します。

  • fromFilePath (変換元ファイルパス)
  • toFilePath(変換先ファイルパス)

その後、Imageクラスでイメージオブジェクトを作成します。

Imageクラスの詳細は以下にドキュメントがあります。

Image Class | Microsoft Docs

次に変換先ファイルパスを指定して Save()メソッドを呼び出します。

最後に Dispose() して終了です。

すごい簡単です。変換フォーマットも拡張子をみて判断してくれているようです。

こんなに簡単にできるなんて、びっくりしました。

画像のサイズ変更

サイズ変更だって簡単にできてしまいます。

using System;
using System.Drawing;

namespace ImgConv
{
    class Program
    {
        static void Main(string[] args)
        {

            int paramLength = 0;
            String fromFilePath = "";
            String toFilePath = "";
            int resizedWidth = 0;
            int resizedHeight = 0;

            paramLength = args.Length;
            fromFilePath = args[0];
            toFilePath = args[1];

            Image orgImage = Image.FromFile(fromFilePath);

            resizedWidth = orgImage.Width;
            resizedHeight = orgImage.Height;

            if (paramLength > 2 )
            {
                resizedWidth = Int32.Parse(args[2]);
                resizedHeight = Int32.Parse(args[3]); 
            }

            Bitmap bmpObj = new Bitmap(orgImage, new Size(resizedWidth, resizedHeight));

            orgImage.Save(toFilePath);

            orgImage.Dispose();
        }
    }
}

一番のミソはここです。


Bitmap bmpObj = new Bitmap(orgImage, new Size(resizedWidth, resizedHeight));
orgImage.Save(toFilePath);

Sizeクラスで幅と高さを設定して、Bitmapオブジェクトを生成しています。

そのあとに Save メソッドで保存しています。

感想

Node.js (TypeScript) には無いものが C# にはあるように思います。 .net core フレームワークがあれば
マルチプラットフォームで動作するのも魅力です。