1. はじめに
ファイルってのは、単なるデータのブロックで、物理的にはどこかのストレージ(ハードディスク、SSD、USBメモリ、フロッピーでもOK!おじいちゃんによろしく!)に保存されてるものだよ。ユーザーから見たら、ファイルは「開く・読む・編集・保存」できる何か、って感じ。
プログラミングの世界だと、ファイルは「名前」と「場所(パス)」を持つバイトの並びで、プログラマー的には「名前・パス(住所)・サイズ・作成日」みたいな属性を持つオブジェクトだね。一番大事なのは、ファイルは永続的(パーシステント)なデータの保存場所ってこと。プログラム実行中のメモリ上のデータは、終了したら消えちゃうけど、ファイルは残るんだ。
ファイルシステムって何?
ファイルシステムは、ディスク上のファイルを保存・整理する仕組みのこと。どこにファイルがあるか、どうやって探すか、誰がアクセスできるか、フォルダ(ディレクトリ)の構造、ファイル名や中身の探し方…全部ファイルシステムが管理してる。
でっかいタンスを想像してみて。引き出しがいっぱいあって、その中にフォルダがあって、さらにその中に書類(ファイル)が入ってる。C#のノートを探したいなら、タンスを開けて、引き出しを見つけて、フォルダを取り出して、その中の紙を探す…みたいな感じ。ファイルシステムはこうやって情報を整理してるんだ。
有名なファイルシステム
- NTFS — Windowsの「標準」ファイルシステム。
- FAT32, exFAT — USBメモリ、SDカード、外付けストレージ用。
- EXT4 — Linuxでよく使われてる。
- APFS, HFS+ — macOS用。
C#プログラマー的には、普段はあんまり気にしなくてOK。.NETが裏側の細かいことは隠してくれるから、「ファイル/フォルダ」って抽象的に扱えばいい。でも、知っておくと便利なこともあるよ。例えば、NTFSだとファイル名にスペースや特殊文字が使えるけど、FAT32だとダメだったりする。
2. ディレクトリ(フォルダ)の仕組み
ディレクトリ(またはフォルダ)は、他のファイルやディレクトリのリストを持つ特別な種類のファイルだよ。ディレクトリツリー(ファイルの階層構造)は、ルートからファイルまでの道筋のこと。例えば、C:\Users\イワン\Documents\MyFile.txtみたいな感じ。
- ルート — ディスクの一番上(C:\)。
- その中にフォルダ(サブフォルダ)があって、さらにその中にファイルや他のフォルダが入ってる。
簡単なイメージ図:
C:\
└── Users\
└── イワン\
├── Documents\
│ └── MyFile.txt
└── Pictures\
└── Cat.jpg
3. ファイルパス(file path)って何?
ファイルパスは、ディレクトリツリーの中でファイルの「住所」みたいなもの。これで目的のファイルやフォルダを一意に見つけられる。
絶対パスと相対パス
- 絶対パス:ファイルシステムのルートから始まるやつ。
Windows: C:\Users\イワン\Documents\MyFile.txt
Linux/macOS: /home/ivan/Documents/MyFile.txt - 相対パス:今いる場所(カレントディレクトリ)からの道筋。
例えば、プログラムがC:\Users\イワンから起動してたら、相対パスDocuments\MyFile.txtで同じファイルにたどり着ける。
カレントディレクトリってのは特別な概念で、相対パスの「基準点」だよ。普通は.exeファイルがある場所か、コンソールを開いた場所になる。
図:絶対パスと相対パス
絶対パス 相対パス
C:\Projects\MyApp\logs\output.txt logs\output.txt
└─ ディスクのルート (C:) └─ MyAppから見た相対
パスの区切り文字:\ と /
Windowsではバックスラッシュ(\)、Linux/macOSでは普通スラッシュ(/)を使うよ。
今の.NETはどっちもサポートしてるけど、1つのプロジェクトで混ぜない方がいい。パスを作るときは、必ず専用のAPI(アプリケーションプログラミングインターフェース)を使ってね。文字列を手でつなげるのはやめよう。
4. プログラムから見たファイル
.NETにはファイル操作用の便利なツールがいっぱいある。主なやつは:
- System.IO.File: ファイルの読み書き・削除・存在チェックなどの静的メソッド。
- System.IO.Directory: フォルダ用の同じようなメソッド。
- System.IO.FileInfoとSystem.IO.DirectoryInfo: ファイル/フォルダのメタデータにアクセスできるオブジェクトラッパー。
- System.IO.Path: パス操作用のヘルパークラス(パスの結合、拡張子や名前の取得など)。
ちょっとしたサンプル
ファイルの存在チェック
using System.IO;
if (File.Exists("data.txt"))
{
Console.WriteLine("ファイル見つかったよ!");
}
else
{
Console.WriteLine("ファイルが見つからない!");
}
ファイルサイズの取得
var info = new FileInfo("data.txt");
Console.WriteLine($"ファイルサイズ: {info.Length} バイト");
これらのサンプルの詳しい動きは、次のレクチャーで解説するから、今は「ふーん、こうやるんだ」くらいでOK!
5. 便利なポイント
ファイルのメタデータ:名前、拡張子、サイズ、日付など
ファイルを扱うとき、中身だけじゃなくて「ファイルのパスポート」みたいな情報も大事だよ:
- 名前 — 人間が見るファイル名。
- 拡張子 — .txt, .jpg, .exe, .csなど。中身が何か(たまに)分かるヒント。
- サイズ — バイト数。
- 作成/更新日時 — いつ作られたか、最後にいつ変わったか。
- 属性 — 例えば「読み取り専用」「隠しファイル」「システムファイル」など。
.NETではFileInfoやDirectoryInfoクラスがこういう情報を扱うのに便利(次回以降のレクチャーでやるよ)。
ファイル拡張子とフォーマット
ファイル拡張子は、名前の後ろに付く「.」以降の部分。例えば、document.txtなら拡張子はtxt。OSは拡張子を見て「どのアプリで開くか」を決めてる(例:.jpgは画像ビューア、.xlsはExcelとか)。
でも、プログラマー的には拡張子は「ヒント」程度。本当のファイルフォーマットは中身で決まる。例えば、MyCat.jpgをテキストエディタで開くと、意味不明な文字列(文字化け)が出てくるだけで、画像じゃない。だから、拡張子は絶対じゃなくて、あくまで目安だって覚えておこう。
ファイルの読み書きの基本
ファイルはバイトの並びだよ。C#でファイルを扱うときは、だいたいこんな流れ:
- ファイルを開く(読み込み用・書き込み用、または両方)。
- データをメモリに読む。
- 新しいデータを書き込む。
- ファイルを閉じる — これ超大事!閉じないとシステムリソースを掴んだままになって、他の人がそのファイルを消せなくなったりする。
今どきの.NETのAPIは親切で、例えばFileクラスはファイルを開いて、読んで、すぐ閉じてくれる。でも、Streamとか大きいファイルを扱うときは、ちゃんと意識しないとダメ(この辺はまた次回!)。
クロスプラットフォームで気をつけること
今のC#はWindows、Linux、macOSでほぼ同じように動く。でも、ちょっとした違いはある。よくあるのは、区切り文字(\ vs /)や、ファイル名の長さ・使えない文字の制限とか。
だから、Path.CombineやSystem.IO.Pathのメソッドを使うのがベスト。これならどのOSでも正しくパスを作ってくれる。絶対にこう書いちゃダメ:
var filePath = "C:\\Users\\Ivan\\data.txt"; // Windows専用!
こっちの方がいい:
var filePath = Path.Combine("Users", "Ivan", "data.txt");
今の作業ディレクトリを知るには?
ファイルがどこに保存されるか知りたいときは、専用のクラスがあるよ:
string currentDir = Environment.CurrentDirectory;
Console.WriteLine($"カレントディレクトリ: {currentDir}");
ちなみに、ユーザーにパスを選ばせたいときは、ファイル/フォルダ選択ダイアログやコマンドライン引数を使うのがオススメ。
GO TO FULL VERSION