ファイルを作成し、そのストリームを取得できます。そのときファイルが存在しないならば、作成されます。
| 戻り値の型 | メソッド | 機能 | 同等の処理 |
|---|---|---|---|
| FileStream | Create(String) | 読み取り、書き込み用にファイルを作成。すでに存在する場合は上書き | new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, FileStream.DefaultBufferSize)
Create - file.cs |
| StreamWriter | CreateText(String) | 書き込み用にテキストファイルを作成。すでに存在する場合は上書き (FileModeはCreate) | new StreamWriter(path,false)
CreateText - file.cs |
| StreamWriter | AppendText(String) | 書き込み用にテキストファイルを作成。すでに存在する場合は追記 | new StreamWriter(path,true)
AppendText - file.cs |
public static System.IO.FileStream Create (string path);Create(String) - File.Create Method (System.IO) | Microsoft Learn
string path = "sample.txt";
using (FileStream fs = File.Create(path))
{
byte value = (byte)'A';
fs.WriteByte(value);
}
public static void Copy (string sourceFileName, string destFileName);Copy(String, String) - File.Copy Method (System.IO) | Microsoft Learn
保存先のdestFileNameが存在していると、IOExceptionが発生します。これを上書きするようにするには、第3引数を持つオーバーロードでtrueを指定します。
public static void Move (string sourceFileName, string destFileName);Move(String, String) - File.Move Method (System.IO) | Microsoft Learn
異なる名前で同じディレクトリへ移動することで、ファイル名の変更 (rename) として機能させられます。
destFileNameの位置にファイルが存在していると、「既に存在するファイルを作成することはできません。(Cannot create a file when that file already exists.)」としてIOExceptionが投げられます。そのときのHResultプロパティの値は、0x800700B7 (-2147024713) で、0xB7 (183) ERROR_ALREADY_EXISTSの意味です。この場合.NET Core 3.0以降ならば、第3引数をtrueとすることで上書きさせられます。それ以外では先に削除してから移動するか、安全にはCopy()で上書きしてから削除するかReplace()で置換します。
sourceFileNameが使用中だと、「パス '**' へのアクセスが拒否されました。 (Access to the path '**' is denied.)」としてIOExceptionが投げられます。そのときのHResultプロパティの値は、0x80131620 (-2146232800) です。
PathTooLongExceptionが投げられるパスの長さの基準は、.NET Framework 4.6.2より前ならば260文字で、以降ならば基本的に32767 (Int16.MaxValue) 文字となります。Remarks - PathTooLongException Class (System.IO) | Microsoft Learn
指定のファイルを、別のファイルに置き換えられます。
public static void Replace ( string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors );Replace(String, String, String, Boolean) - File.Replace メソッド (System.IO) | Microsoft Learn
sourceFileNameを、destinationFileNameに置き換えられます。つまりsourceFileNameが、destinationFileNameの位置に移動します。これら2つのファイルが存在していないと、FileNotFoundExceptionが投げられます。
このメソッドは内部ではWin32のReplaceFile()を呼ぶだけのため、処理はそれに準じます。そのため次の属性が保持されます。 Replace - file.cs Remarks - ReplaceFileA 関数 (winbase.h) - Win32 apps | Microsoft Learn
FileSystemWatcherで変更を監視すると、バックアップを作成する場合は
File.Replace("src.txt", "dest.txt", "dest_bk.txt");
Renamed : dest.txt -> dest_bk.txt Renamed : src.txt -> dest.txt
のように名前が変更されるだけですが、作成しないと
File.Replace("src.txt", "dest.txt", null);
Created : dest.txt~RF***.TMP Deleted : dest.txt~RF***.TMP Renamed : dest.txt -> dest.txt~RF***.TMP Renamed : src.txt -> dest.txt Deleted : dest.txt~RF***.TMP
のように一時ファイルが作成された上で削除されます。
ファイルを開き、そのストリームを取得できます。
| 戻り値の型 | メソッド | 機能 | 同等の処理 | ファイルが存在しない場合 |
|---|---|---|---|---|
| FileStream | Open(String, FileMode) | 読み取り、書き込み用にファイルを開く | new FileStream(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.None)
Open - file.cs |
FileModeの指定による |
| FileStream | OpenRead(String) | 読み取り用にファイルを開く | new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
OpenRead - file.cs |
FileNotFoundException例外 |
| StreamReader | OpenText(String) | 読み取り用にテキストファイルを開く | new StreamReader(path)
OpenText - file.cs |
FileNotFoundException例外 |
| FileStream | OpenWrite(String) | 書き込み用にファイルを開く | new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
OpenWrite - file.cs |
ファイルを作成する |
public static System.IO.FileStream Open (
string path,
System.IO.FileMode mode,
System.IO.FileAccess access,
System.IO.FileShare share
);
Open(String, FileMode, FileAccess, FileShare) - File.Open Method (System.IO) | Microsoft Learn
accessを省略したとき、modeがAppendならばWriteに、それ以外ならばReadWriteになります。またshareを省略するとNoneになります。Open - file.cs
読み取り専用のファイルを開くときにFileAccess.Readを指定しないと、UnauthorizedAccessExceptionが発生します。
FileStream fileStream
= File.Open("sample.dat", FileMode.Create, FileAccess.Write, FileShare.Read);
| 列挙子 | 数値 | 意味 |
|---|---|---|
| CreateNew | 1 | ファイルを作成する。すでに存在するならばIOExceptionが投げられる |
| Create | 2 | ファイルが存在するならばTruncateと同じ、存在しないならばCreateNewと同じ |
| Open | 3 | ファイルを開く。存在しないならばFileNotFoundExceptionが投げられる |
| OpenOrCreate | 4 | ファイルが存在するならば開く、存在しないならば作成する |
| Truncate | 5 | ファイルを開き、サイズが0バイトに切り詰められる (truncate) |
| Append | 6 | ファイルが存在するならば開き末尾までシークする、存在しないならば作成する |
| 列挙子 | 数値 | 意味 |
|---|---|---|
| Read | 1 | ファイルから読み取れる |
| Write | 2 | ファイルに書き込める |
| ReadWrite | 3 | ファイルからの読み取りと書き込みをできる |
| 列挙子 | 数値 | 意味 |
|---|---|---|
| None | 0 | 現在のファイルの共有を拒否する。ファイルを閉じるまで、ファイルを開く要求は失敗する |
| Read | 1 | 読み取り用にファイルを開くことを許可する。ファイルを閉じるまで、ファイルを読み取り用に開く要求は失敗する |
| Write | 2 | 書き込み用にファイルを開くことを許可する |
| ReadWrite | 3 | 読み取りまたは書き込み用にファイルを開くことを許可する |
| Delete | 4 | 削除を許可する |
| Inheritable | 16 | 子プロセスがファイル ハンドルを継承できるようにする。Win32では直接サポートされない |
string path = "sample.dat"; FileStream fs1 = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); FileStream fs2 = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); // ok FileStream fs3 = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None); // IOException「別のプロセスで使用されているため、プロセスはファイル 'sample.dat' にアクセスできません。」
指定ファイルを削除できます。
public static void Delete(
string path
)
File.Delete(String) メソッド (System.IO) | Microsoft Learn
下表のような状況で例外が投げられます。
| 状況 | 例外 |
|---|---|
| ファイルまでのパスが存在しない | System.IO.DirectoryNotFoundException |
| ファイルは存在するが、使用中 | System.IO.IOException |
| ファイルは存在するが、読み取り専用 | System.UnauthorizedAccessException |
DeleteFile()でERROR_FILE_NOT_FOUNDが返されたときは無視されるため、ファイルまでのパスは存在するがそこにファイルが存在しないときは、例外は投げられず何も通知されません。 Delete - file.cs
さまざまな要因で削除に失敗するため、File.Exists()でアクセスできることを確認してから削除するのが確実です。
public static bool Exists (string path);File.Exists(String) Method (System.IO) | Microsoft Learn
pathにアクセス可能ならば、trueが返されます。アクセスできなければfalseとなり、それには次のような場合も該当します。
| 戻り値 | メソッド | 機能 |
|---|---|---|
| IEnumerable<string> | ReadLines(String) | ファイルの行を読み込める |
| string[] | ReadAllLines(String) | ファイルのすべての行を読み込める |
| string | ReadAllText(String) | ファイルのすべてのテキストを読み込める |
| byte[] | ReadAllBytes(String) | ファイルの内容をバイト配列に読み込める |
string path = "sample.txt"; // 取得 DateTime dateTime1 = File.GetCreationTime(path); // 作成日時 (Created) DateTime dateTime2 = File.GetLastWriteTime(path); // 更新日時 (Modified) DateTime dateTime3 = File.GetLastAccessTime(path); // アクセス日時 (Accessed) FileAttributes attributes = File.GetAttributes(path); // 属性 // 設定 File.SetCreationTime(path, DateTime.Now);File.GetCreationTime メソッド (String) (System.IO) | MSDN
指定のファイルが存在しない場合、GetCreationTime()などの日時を取得するメソッドからは、ローカル時間に調整された1601/01/01 0:00:00(UTC) が返されます。一方でGetAttributes()からはFileNotFoundExceptionが投げられます。
BitLockerによりロックされている場合は、「このドライブは、BitLocker ドライブ暗号化でロックされています。コントロール パネルからドライブのロックを解除してください。(This drive is locked by BitLocker Drive Encryption. You must unlock this drive from Control Panel.)」そしてHResultは0x80370000 (-2143879168) で、IOExceptionが投げられます。
同様の内容は、FileInfoではプロパティとして取得できます。
string path = "sample.txt"; FileInfo fileInfo = new FileInfo(path); // 取得 DateTime dateTime1 = fileInfo.CreationTime; // 作成日時 DateTime dateTime2 = fileInfo.LastWriteTime; // 更新日時 DateTime dateTime3 = fileInfo.LastAccessTime; // アクセス日時 FileAttributes attributes = fileInfo.Attributes; // 属性 long size = fileInfo.Length; // サイズ // 設定 fileInfo.CreationTime = DateTime.Now;FileSystemInfo.CreationTime プロパティ (System.IO) | MSDN
指定のファイルが存在しない場合、File.GetAttributes()では例外が投げられますが、FileInfo.Attributesからは-1が返されます。c# - Why is the FileAttributes value for a file which does not exist -1? - Stack Overflow
ファイルとディレクトリの属性を表します。
| 列挙子 | 値 | 内容 |
|---|---|---|
| ReadOnly | 1 | 読み取り専用 |
| Hidden | 2 | 隠しファイル |
| System | 4 | システム ファイル |
| Directory | 16 | ファイルはディレクトリ |
| Archive | 32 | 増分バックアップ操作対象としてマークされている |
| Device | 64 | (将来使用するための予約) |
| Normal | 128 | 特別な属性を持たない標準ファイル |
| Temporary | 256 | 一時ファイル |
| SparseFile | 512 | スパース ファイル (データの大部分が0である大きなファイル) |
| ReparsePoint | 1024 | リパース ポイント (ファイルまたはディレクトリに関連付けられたユーザー定義のデータ ブロック) が含まれている |
| Compressed | 2048 | 圧縮ファイル |
| Offline | 4096 | ファイルはオフライン |
| NotContentIndexed | 8192 | コンテンツ インデックス サービスでインデックスされない |
| Encrypted | 16384 | ファイルまたはディレクトリは、暗号化されている (ファイルの場合は、ファイルのすべてのデータが暗号化されている。 ディレクトリの場合は、新規作成されるファイルおよびディレクトリが既定で暗号化される) |
| IntegrityStream | 32768 | ファイルまたはディレクトリには、データ整合性のサポートが含まれる |
| NoScrubData | 131072 | ファイルまたはディレクトリは、データ整合性のスキャン対象から除外される |
ロックされているかどうかは、アクセス時に発生する例外から調べられます。
try
{
using (File.Open(filePath, FileMode.Open, FileAccess.Read)) { }
}
catch (IOException e)
{
int errorCode = e.HResult & 0xffff;
if (errorCode == 0x20 || errorCode == 0x21)
{
// ロックされている
}
}
c# - How to check for file lock? - Stack Overflow
.net - How can I programmatically tell if a caught IOException is because the file is being used by another process, without resorting to parsing the exception's Message property? - Stack Overflow
.NET 4.5より前はException.HResultのアクセス修飾子がprotectedとなっているため、それの代わりに
int errorCode = Marshal.GetHRForException(e) & 0xffff;
のようにGetHRForException()から取得する必要があります。Community Additions - Exception.HResult Property (System)
[SecurityCriticalAttribute]
public static int GetHRForException(
Exception e
)
Marshal.GetHRForException メソッド (Exception) (System.Runtime.InteropServices) | MSDN
エラーコードの意味は、それぞれ下表のように定義されています。
| コード | 定数 | 意味 | 例外メッセージ |
|---|---|---|---|
| 32 (0x20) | ERROR_SHARING_VIOLATION | 他のプロセスによって使用されているため、プロセスはファイルにアクセスできない。共有違反 | 「別のプロセスで使用されているため、プロセスはファイル '***' にアクセスできません。」 |
| 33 (0x21) | ERROR_LOCK_VIOLATION | 他のプロセスがファイルの一部をロックしているため、プロセスはファイルにアクセスできない。 | 「プロセスはファイルにアクセスできません。別のプロセスがファイルの一部をロックしています。」 |
IOExceptionが投げられなくなるまで、くりかえしファイルにアクセスします。Wait until file is unlocked in .NET - Stack Overflow
Win32の再起動マネージャー (Restart Manager) で、ファイルをロックしているプロセスの情報を得られます。
DWORD RmGetList( [in] DWORD dwSessionHandle, [out] UINT *pnProcInfoNeeded, [in, out] UINT *pnProcInfo, [in, out, optional] RM_PROCESS_INFO [] rgAffectedApps, [out] LPDWORD lpdwRebootReasons );RmGetList function (restartmanager.h) - Win32 apps | Microsoft Learn
lpdwRebootReasonsで返される値の意味は、次のようになります。
typedef enum _RM_REBOOT_REASON {
RmRebootReasonNone = 0x0, // Reboot not required
RmRebootReasonPermissionDenied = 0x1, // Current user does not have permission to shut down one or more detected processes
RmRebootReasonSessionMismatch = 0x2, // One or more processes are running in another TS session.
RmRebootReasonCriticalProcess = 0x4, // A critical process has been detected
RmRebootReasonCriticalService = 0x8, // A critical service has been detected
RmRebootReasonDetectedSelf = 0x10 // The current process has been detected
} RM_REBOOT_REASON;
RestartManager.h
RM_REBOOT_REASON (restartmanager.h) - Win32 apps | Microsoft Learn