ここでは「テストファイル作成ソフト」というWindowsアプリケーションを作成します。

概要

システム開発をする中で、保存先の容量が不足した場合の動作試験を行なうことがあります。
数GB、数TBといったファイルを手操作で作成することは困難なため試験用のツールとして作成してみます。

ファイルの作成だけであればfsutilコマンドなどのコマンドで簡単に実現することができます。
ただし、アプリケーションであれば細かな制御、例えば100GBのファイルを30秒間隔で作成するといった試験内容に合わせてカスタマイズすることができます。

カスタマイズもfsutilコマンドとバッチを組み合わせすれば可能ではあります。本アプリにチャレンジするか否かはご判断ください。

プロジェクトを作成する

はじめにプロジェクトを作成します。

開発環境

OSはWindowsを使用します。
開発環境が動作するOSであれば他のバージョン(Windows 11など)でも構いません。

開発環境はVisual Studio 2022を使用します。
次に指定する.NET Frameworkは古いバージョンからありますので、古いVisual Studioでも構いません。

Visual Studio 2022を起動後、新しいプロジェクトの作成にて「Windows フォームアプリケーション (.NET Framework)」を選択します。

注意

名前の似ているプロジェクト「Windows フォームアプリ」がありますが、選択しないでください。

こちらで使用するフレームワーク「.NET」はOSにインストールされておらず、別途インストールする必要です。今回は「.NET Framework」を使用します。

.NETと.NET Frameworkの違いについてはマイクロソフト社のホームページより確認することができます。

.NET Frameworkのバージョンは4.7.2を使用しましたが、古いバージョンでも構いません。
最新のバージョンはOSにインストールされていない可能性があります。

プログラム

ここからは実装を進めていきます。まずはコントロールをセットします。

今回使用するコントロールは「TextBox」と「Button」の2つになります。

  • TextBox:サイズを入力するためのコントロール。入力したサイズのファイルを作成します。
  • Button:クリックするとファイルを作成します。

また、フォームのサイズをコントロールのサイズに合わせて小さくし、ボタンの名前も「作成」に変更します。

次にボタンのクリックイベントにファイル作成を行なうソースコードを入力します。
25行目〜38行目まではクリックイベント時の処理になります。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace test_file
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// ボタンクリック
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {            
            long size;

            // ファイルサイズを取得
            if (long.TryParse(textBox1.Text, out size) == true && size >= 0)
            {                
                using (System.IO.FileStream fi = new System.IO.FileStream("testfile", System.IO.FileMode.Create))
                {
                    // ファイルの長さを設定
                    fi.SetLength(size);
                }
            }
        }
    }
}
  1. 最初にテキストボックスからサイズを受け取るための変数(size)を作成します。
  2. TryParse関数よりテキストボックスからサイズを受け取ります。
    この関数はlong型に変換成功した場合のみtrueを返信します。
    ただし、負の数の場合がありますので0以上をAND条件で追加します。
  3. ファイルを作成します。作成にはFileStreamクラスを使用します。
    ここではtestfileという試験ファイルを作成します。
  4. 最後にFileStreamクラスのSetLength関数を実行します。
    引数にはsize変数を指定します。
    これでファイルにデータ書き込みを行わなくとも指定したサイズのファイルが作成されます。

プログラム部分はこれだけです。
下図は1GBで実行した結果です。指定したサイズのファイルが作成されています。

次章(カスタマイズ)では少し応用して一定時間毎に自動作成するカスタマイズを行います。

カスタマイズ

一定時間毎に指定したサイズのファイルを作成するようにプログラムを変更します。

コントロールの追加

次のコントロールを追加します。

  • TextBox:作成間隔を入力するためのコントロール。単位を「秒」、初期値を「10」とします。
  • Button:一定時間による作成開始と停止を行なうためのボタン。起動時の名前は「開始」とします。
  • Timer:Windows.Forms.Timerを使用します。コントロールとしてセットできます。
  • Label:コントロールを判別するため、ラベルを配置します。

定数と変数の追加

次に定数(TestFileName)とメンバ変数(_fileCount)を追加します。

TestFileNameは「作成」クリックと一定時間毎に作成するファイル名として使用します。

一定時間毎に作成するファイルは[TestFileName(定数)]_[_fileCount(変数)]で作成します。
_fileCountは作成後にインクリメントします。

    public partial class Form1 : Form
    {
        /// <summary>
        /// テストファイル名
        /// </summary>
        private const string TestFileName = "testfile";

        /// <summary>
        /// ファイルのカウント
        /// </summary>
        private int _fileCount;

ファイル作成処理を関数にする

ファイルを作成する処理は「作成」ボタンのクリックとタイマー処理の両方で使用します。
このため関数にします。

処理内容は前章と同じですが、引数で作成するファイル名を指定できるようにしています。

/// <summary>
/// テストファイル作成
/// </summary>
/// <param name="file">ファイル名</param>
private void CreateTestFile(string file)
{
    long size;

    // ファイルサイズを取得
    if (long.TryParse(textBox1.Text, out size) == true && size >= 0)
    {
        using (FileStream fi = new FileStream(file, FileMode.Create))
        {
            // ファイルの長さを設定
            fi.SetLength(size);
        }
    }
}

「作成」ボタンのクリックでは上の関数を呼び出すように変更します。
引数(ファイル名)には定数(TestFileName)を指定します。

        /// <summary>
        /// 作成ボタンクリック
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            CreateTestFile(TestFileName);
        }

タイマー処理

タイマー処理はTickイベント内に記載します。

引数でstring.Format関数を使用し、[TestFileName(定数)]_[_fileCount(変数)]の形で順番にファイルを作成します。
_fileCount変数は作成後にインクリメントします。
これにより、タイマーが呼び出されると番号順のファイルを作成することができます。

/// <summary>
/// タイマー処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer1_Tick(object sender, EventArgs e)
{
    CreateTestFile(string.Format("{0}_{1}", TestFileName, _fileCount));
    _fileCount++;
}

タイマーの開始と停止

最後にタイマー開始と停止を処理するボタンについて記述します。
タイマーの動作状態をチェックすることで、1つのボタンから開始と停止の両方を処理します。

/// <summary>
/// 開始/停止ボタンクリック
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
    if (timer1.Enabled != true)
    {
        int interval;

        if (int.TryParse(textBox2.Text, out interval) == true && interval > 0)
        {
            // ファイルのカウントをリセット
            _fileCount = 1;

            // タイマー開始
            timer1.Interval = interval * 1000;
            timer1.Start();

            ((Button)sender).Text = "停止";
        }
    }
    else
    {
        // タイマー停止
        timer1.Stop();

        ((Button)sender).Text = "開始";
    }          
}
  1. Enabledプロパティよりタイマーが開始中か停止中か判定します。
  2. タイマーが停止中の場合は変数(interval)にテキストボックスより取得したタイマーの間隔値を取得します。
    取得方法や負数チェックはサイズの取得と同様ですが、こちらは1以上の場合に真とします。
  3. カウントリセット(_fileCountを1にする)後、Start関数でタイマーを開始します。
    タイマー間隔はミリ秒(1/1000秒)のため、1000をかけ算します。
  4. 引数(sender)は自身のコントロールのため、Buttonクラスでキャストすることができます。
    キャスト後にボタンテキストを「停止」に変更します。
  5. タイマーが開始中の場合も同じ考え方です。
    Stop関数でタイマーを停止後、ボタンテキスト「開始」に変更します。

動作確認

実行して動作確認します。

例としてファイルサイズを1000byte、10秒間隔で作成開始します。
番号順にファイルが作成されました。

変更したソースコード(全体)になります。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace test_file
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// テストファイル名
        /// </summary>
        private const string TestFileName = "testfile";

        /// <summary>
        /// ファイルのカウント
        /// </summary>
        private int _fileCount;

        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 作成ボタンクリック
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            CreateTestFile(TestFileName);
        }
                
        /// <summary>
        /// 開始/停止ボタンクリック
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (timer1.Enabled != true)
            {
                int interval;

                if (int.TryParse(textBox2.Text, out interval) == true && interval > 0)
                {
                    // ファイルのカウントをリセット
                    _fileCount = 1;

                    // タイマー開始
                    timer1.Interval = interval * 1000;
                    timer1.Start();

                    ((Button)sender).Text = "停止";
                }
            }
            else
            {
                // タイマー停止
                timer1.Stop();

                ((Button)sender).Text = "開始";
            }          
        }

        /// <summary>
        /// タイマー処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            CreateTestFile(string.Format("{0}_{1}", TestFileName, _fileCount));
            _fileCount++;
        }

        /// <summary>
        /// テストファイル作成
        /// </summary>
        /// <param name="file">ファイル名</param>
        private void CreateTestFile(string file)
        {
            long size;

            // ファイルサイズを取得
            if (long.TryParse(textBox1.Text, out size) == true && size >= 0)
            {
                using (FileStream fi = new FileStream(file, FileMode.Create))
                {
                    // ファイルの長さを設定
                    fi.SetLength(size);
                }
            }
        }
    }
}

まとめ

このように簡単にテストファイルを作成することができます。
今回は一例になりますが、応用することで業務システムのテストツールといった使い方もできるかもしれません。
ご参考になれば嬉しいです。