はじめに 一時ファイルは「使い捨ての作業机」
業務システムを書いていると、「ちょっとだけデータを置いておきたい」場面がよく出てきます。
たとえば、大きなファイルを分割して処理するときの中間結果、ダウンロード中の一時データ、圧縮前の展開ファイルなどです。
こういうときに、いきなり本番の保存先に書くのではなく、「一時ファイル」に書いておいて、処理が成功したら本番に移動、失敗したら捨てる、という設計にすると安全性がぐっと上がります。
C# には、この「一時ファイル」を簡単に作るための仕組みが標準で用意されています。
ここでは、初心者向けに「一時ファイルとは何か」「どう作るか」「どう片付けるか」を、実務で使えるユーティリティという視点で丁寧に解説していきます。
一時ファイルの基本 Path.GetTempFileName と Path.GetTempPath
一時フォルダの場所を知る Path.GetTempPath
まず、「一時ファイルをどこに作るか」という話からです。
C# では、Path.GetTempPath() を呼ぶと、OS が用意している「一時フォルダ」のパスを取得できます。
using System;
using System.IO;
class Program
{
static void Main()
{
string tempDir = Path.GetTempPath();
Console.WriteLine("一時フォルダ: " + tempDir);
}
}
C#Windows なら、だいたい C:\Users\ユーザー名\AppData\Local\Temp\ のような場所が返ってきます。
「一時ファイルはここに作る」というのが基本ルールです。自分で勝手に C ドライブ直下などに作るより、OS 標準の場所を使ったほうが安全で、クリーンアップの対象にもなりやすいです。
一時ファイルを作る Path.GetTempFileName
実際に一時ファイルを作るには、Path.GetTempFileName() を使います。
using System;
using System.IO;
class Program
{
static void Main()
{
string tempFilePath = Path.GetTempFileName();
Console.WriteLine("作成された一時ファイル: " + tempFilePath);
}
}
C#ここで重要なのは、このメソッドを呼んだ瞬間に「ディスク上に 0 バイトの空ファイルが実際に作られる」という点です。
戻り値は、その一時ファイルの「絶対パス」です。拡張子は .tmp になります。
つまり、「一時ファイルのパスをもらう」だけでなく、「ファイル自体ももう存在している」状態になります。
あとはこのパスに対して File.WriteAllText や FileStream などで自由に読み書きできます。
一時ファイルのライフサイクル 「作る→使う→必ず消す」
典型的な流れをコードで見る
一時ファイルは「作りっぱなし」にしてはいけません。
作業が終わったら、必ず削除する、というのが鉄則です。
典型的な流れを一つのサンプルで見てみましょう。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main()
{
string tempFilePath = Path.GetTempFileName();
Console.WriteLine("一時ファイル: " + tempFilePath);
try
{
string content = "これは一時ファイルに書き込むテキストです。";
File.WriteAllText(tempFilePath, content, Encoding.UTF8);
string read = File.ReadAllText(tempFilePath, Encoding.UTF8);
Console.WriteLine("読み出した内容: " + read);
Console.WriteLine("ここで本来の処理(アップロード、変換など)を行うイメージです。");
}
finally
{
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
Console.WriteLine("一時ファイルを削除しました。");
}
}
}
}
C#ここで深掘りしたいポイントは二つです。
一つ目は、「try-finally で囲んでいる」ことです。
途中で例外が発生しても、finally ブロックは必ず実行されるので、一時ファイルを確実に削除できます。
二つ目は、「削除前に File.Exists で存在チェックをしている」ことです。
処理の途中で別の箇所が削除している可能性もあるので、「存在していたら消す」という書き方にしておくと安全です。
using と FileStream を組み合わせるパターン
ストリームで扱いたい場合は、FileStream と using を組み合わせることが多いです。
using System;
using System.IO;
class Program
{
static void Main()
{
string tempFilePath = Path.GetTempFileName();
Console.WriteLine("一時ファイル: " + tempFilePath);
try
{
using (var stream = new FileStream(
tempFilePath,
FileMode.Open,
FileAccess.ReadWrite,
FileShare.None))
{
byte[] data = { 1, 2, 3, 4, 5 };
stream.Write(data, 0, data.Length);
stream.Position = 0;
int b;
Console.Write("読み出し: ");
while ((b = stream.ReadByte()) != -1)
{
Console.Write(b + " ");
}
Console.WriteLine();
}
}
finally
{
if (File.Exists(tempFilePath))
{
File.Delete(tempFilePath);
Console.WriteLine("一時ファイルを削除しました。");
}
}
}
}
C#using によってストリームは確実に閉じられますが、ファイル自体は残るので、やはり最後に File.Delete が必要です。
「リソースの解放(ストリームを閉じる)」と「ファイルの削除」は別物だ、という感覚を持っておくと混乱しません。
実務で使える一時ファイルユーティリティクラス
一時ファイルを「使い捨てオブジェクト」として扱う
毎回 try-finally と Delete を書くのは面倒なので、「使い終わったら自動で消える一時ファイル」をクラスとして用意しておくと便利です。IDisposable を実装して、using で囲んだら最後に削除される、というイメージです。
using System;
using System.IO;
public sealed class TempFile : IDisposable
{
public string Path { get; }
public TempFile()
{
Path = System.IO.Path.GetTempFileName();
}
public void Dispose()
{
try
{
if (File.Exists(Path))
{
File.Delete(Path);
}
}
catch
{
}
}
}
C#使い方はとてもシンプルです。
class Program
{
static void Main()
{
using (var temp = new TempFile())
{
Console.WriteLine("一時ファイル: " + temp.Path);
File.WriteAllText(temp.Path, "一時データ");
string read = File.ReadAllText(temp.Path);
Console.WriteLine("読み出し: " + read);
}
Console.WriteLine("using を抜けた時点で一時ファイルは削除済みです。");
}
}
C#ここでの重要ポイントは、「一時ファイルのライフサイクルをクラスに閉じ込めている」ことです。
呼び出し側は「using で囲む」というルールだけ守れば、削除漏れを心配しなくてよくなります。
Path.GetTempFileName と Path.GetRandomFileName の違い
GetTempFileName は「ファイルを作る」、GetRandomFileName は「名前だけ」
一時ファイル関連でよく出てくるもう一つのメソッドが Path.GetRandomFileName() です。
これは「ランダムなファイル名(文字列)を返すだけ」で、ファイル自体は作りません。
using System;
using System.IO;
class Program
{
static void Main()
{
string randomName = Path.GetRandomFileName();
Console.WriteLine("ランダム名: " + randomName);
string tempDir = Path.GetTempPath();
string tempFilePath = Path.Combine(tempDir, randomName);
Console.WriteLine("一時ファイル候補: " + tempFilePath);
}
}
C#GetTempFileName は「一時フォルダに 0 バイトのファイルを実際に作る」のに対して、GetRandomFileName は「衝突しにくいランダムな名前だけを返す」という違いがあります。
実務では、次のような使い分けが多いです。
すぐに使う一時ファイルが欲しい → Path.GetTempFileName
自分でフォルダを決めて、その中にランダム名でファイルを作りたい → Path.GetRandomFileName と File.Create などを組み合わせる
ランダム名+自前作成のユーティリティ例
自分で一時フォルダを決めて、その中にランダム名で一時ファイルを作るユーティリティもよく使います。
public static class TempFileUtil
{
public static string CreateTempFileIn(string directory)
{
if (string.IsNullOrWhiteSpace(directory))
{
throw new ArgumentException("ディレクトリが空です。", nameof(directory));
}
Directory.CreateDirectory(directory);
string fileName = Path.GetRandomFileName();
string fullPath = Path.Combine(directory, fileName);
using (File.Create(fullPath))
{
}
return fullPath;
}
}
C#これを使えば、例えば「アプリ専用の一時フォルダ」を作って、その中だけで一時ファイルを管理する、といった設計ができます。
一時ファイルを業務で使うときの注意点
削除しないと「Temp がゴミだらけ」になる
一時ファイルは「使い捨て」が前提なので、削除しないとどんどん溜まっていきます。
長期間動き続けるバッチやサービスでは、これがディスク圧迫の原因になります。
だからこそ、「一時ファイルを作ったら、必ずどこかで消す」というルールを徹底する必要があります。TempFile クラスのように、「削除を忘れにくい形」にしておくのは、そのための工夫です。
セキュリティと機密情報
一時ファイルには、機密性の高いデータ(個人情報、トークン、パスワードなど)が一時的に書かれることもあります。
削除したからといって、ディスク上のデータが完全に消えるわけではない、という点も頭の片隅に置いておくとよいです。
本当に機密性が高い場合は、「そもそもディスクに書かない」「暗号化して書く」「OS の暗号化機能が有効な領域を使う」など、別の対策も検討します。
ただ、一般的な業務アプリでは、「不要になったらすぐ削除する」だけでもリスクはかなり下がります。
まとめ 実務で使える「一時ファイル作成」ユーティリティの考え方
一時ファイルは、「本番データを汚さずに、安全に作業するための一時的な作業机」です。
C# では Path.GetTempPath と Path.GetTempFileName を使うことで、OS 標準の一時フォルダに簡単に一時ファイルを作れます。
大事なのは、「作ること」よりも「どう片付けるか」です。
try-finally で必ず削除する、IDisposable な TempFile クラスでライフサイクルを閉じ込める、といった工夫をしておくと、削除漏れによるトラブルを防げます。

