web-dev-qa-db-ja.com

C#でFile.Delete()を試行せずに成功するかどうかを確認するにはどうすればよいですか?

C#では、System.IO.File.Delete(filePath)は、指定されたファイルを削除するか、例外を発生させます。現在のユーザーにファイルを削除する権限がない場合は、UnauthorizedAccessExceptionが発生します。

削除によってUnauthorizedAccessExceptionがスローされる可能性があるかどうかを事前に判断できる方法はありますか(つまり、ACLにクエリを実行して、現在のスレッドのIDに指定されたファイルを削除する権限があるかどうかを確認します)。

私は基本的にやりたいと思っています:

if (FileIsDeletableByCurrentUser(filePath)) {
    /* remove supporting database records, etc. here */
    File.Delete(filePath);
}

しかし、FileIsDeletableByCurrentUser()を実装する方法がわかりません。

30
Dylan Beattie

FileIsDeletableByCurrentUserの実装に関する問題は、それが不可能なことです。その理由は、ファイルシステムが絶えず変化するアイテムであるためです。

ファイルシステムに対して行うチェックと次の操作の間に、任意の数のイベントが発生する可能性があります。含む...

  • ファイルの権限が変更される可能性があります
  • ファイルが削除される可能性があります
  • ファイルは別のユーザー/プロセスによってロックされている可能性があります
  • ファイルが保存されているUSBキーを削除できます

あなたが書くことができる最高の関数は、最も適切にはFileWasDeletableByCurrentUserという名前になります。

17
JaredPar

試しましたか System.IO.File.GetAccessControl(filename) そのファイルのアクセス許可に関する情報を含むFileSecurityを返すはずです。

8
Dale

厳密に言えば、UnauthorizedAccessExceptionはパスがディレクトリであることを意味するため、System.IO.Path.GetFileName(path)タイプのコマンドを使用して、引数の例外をキャッチできます。

ただし、より包括的なソリューションが必要な場合は、DaleHalliwellが述べたようにSystem.IO.File.GetAccessControlを使用してください。

2
Tim Joseph

上記のように。ファイルのアクセス許可を検索し、アプリケーションを実行しているユーザーと比較します。

あなたはいつでもこのアプローチを使うことができます

bool deletemyfile()  
{  
    try  
    {  
        ...delete my file  
        return true;  
    }  
    catch  
    {  
        return false;  
    }  
}

falseが返された場合、trueが返された場合は失敗したことがわかります。あなたが何を求めているのか正確にはわかりませんが、これは私が考えることができる最高のものでした

1
Jonas B

次の順序で行う方が簡単なようです。

  1. 他の部分(データベースデータの削除など)を実行するために、ファイルについて必要な情報を取得します。
  2. ファイルを削除してみてください
  3. ファイルが正常に削除されたら、残りの「クリーンアップ」作業を実行します。正常に削除できない場合は、例外を返す/処理するなど。
0
BBlake

もちろん、System.IOと、おそらく現在のユーザーと組み合わせたファイルのACLセキュリティを使用してReadOnlyフラグを確認することもできますが、Mehrdadがコメントに書いているように、すべての場合に完全に保護されるわけではありません。したがって、例外の場合は常に例外処理が必要になります(たとえそれが トップレベルのキャッチオール であっても、「予期しない問題」をログに記録/表示し、アプリケーションを強制終了します)。

0
peSHIr

そのファイルのアクセス制御リスト(ACL)を取得する必要があります。

ただし、読み取り専用フラグがまだ設定されているか、別のプログラムがファイルをロックしているため、必ずしも実際に削除できるとは限りません。

0
codymanix