29


15

Try / Catchブロックの機能と、それを使用することが重要な理由を理解しました。 しかし、私はいつ、どこでそれらを使うべきかを知っているのです。 何かアドバイス? 誰かが私の例のためにいくつかの勧告をする時間があることを願って、私は下記の私のコードのサンプルをポストするつもりです。

public AMPFileEntity(文字列ファイル名){transferFileList tfl = new transferFileList(); _AMPFlag = tfl.isAMPFile(filename); _requiresPGP = tfl.pgpRequired(filename); _filename = filename.ToUpper(); _fullSourcePathAndFilename = ConfigurationSettings.AppSettings.Get( "sourcePath")_filename; _fullDestinationPathAndFilename = ConfigurationSettings.AppSettings.Get( "FTPStagePath")_filename; _hasBeenPGPdPathAndFilename = ConfigurationSettings.AppSettings.Get( "originalsWhichHaveBeenPGPdPath"); }

public int processFile(){

StringBuilder sb = new StringBuilder(); sb.AppendLine( ""); sb.AppendLine( "--------------------------------"); sb.AppendLine( "ファイル名:" _filename); sb.AppendLine( "AMPFlag:" _AMPFlag); sb.AppendLine( "PGPが必要です:" _requiresPGP); sb.AppendLine( "--------------------------------"); sb.AppendLine( "");

string str = sb.ToString(); UtilityLogger.LogToFile(str); if(_AMPFlag){if(_requiresPGP == true){encryptFile(); } else {UtilityLogger.LogToFile( "このファイルは暗号化を必要としません。 ファイルをFTPStageディレクトリに移動します。 "); if(File.Exists(_fullDestinationPathAndFilename)){UtilityLogger.LogToFile(_fullDestinationPathAndFilename)"は既に存在します。 そのファイルをアーカイブします。 "); if(File.Exists(_fullDestinationPathAndFilename" _archive ")){UtilityLogger.LogToFile(_fullDestinationPathAndFilename" _archive)は既に存在します。 "); File.Delete(_fullDestinationPathAndFilename" _archive ");} File.Move(_fullDestinationPathAndFilename、_fullDestinationPathAndFilename" _archive ");} File.Move(_fullSourcePathAndFilename、_fullDestinationPathAndFilename)ユーティリティファイルAMP転送ファイルではありません。 このファイルをスキップします。 ");}

(0)を返します。 }

private int encryptFile(){

UtilityLogger.LogToFile( "このファイルは暗号化が必要です。 暗号化処理を開始しています。 ");

//最初に宛先ディレクトリにある既存のPGPdファイルをチェックします。 存在する場合はアーカイブします。そうでない場合は保存されません。 上書きしません。 string pgpdFilename = _fullDestinationPathAndFilename ".PGP";


if(File.Exists(pgpdFilename)){UtilityLogger.LogToFile(pgpdFilename ")はすでにFTPStageディレクトリに存在します。 そのファイルをアーカイブします。 "); if(File.Exists(pgpdFilename" _archive ")){UtilityLogger.LogToFile(pgpdFilename" _archive)は既に存在します。 上書きします。 "); File.Delete(pgpdFilename" _archive ");} File.Move(pgpdFilename、pgpdFilename" _archive ");}

プロセスpProc = new Process(); pProc.StartInfo.FileName = "pgp.exe";

string strParams = @ " - " _fullSourcePathAndFilename "を暗号化します--recipient infinata --output" _fullDestinationPathAndFilename ".PGP";

UtilityLogger.LogToFile( "暗号化ファイル。 Params: "strParams); pProc.StartInfo.Arguments = strParams; pProc.StartInfo.UseShellExecute = false; pProc.StartInfo.RedirectStandardOutput = true; pProc.Start(); pProc.WaitForExit();

//これでPGPdになったので、 'hasBeenPGPd' dir UtilityLogger.LogToFile( "PGP暗号化が完了しました。 暗号化されていない元のファイルを "_hasBeenPGPdPathAndFilename)に移動します。 上書きします。 ")File.Delete(_hasBeenPGPdPathAndFilename _filename" original_which_has_been_pgpd ");} File.Move(_fullSourcePathAndFilename、_hasBeenPGPdPathAndFilename _filename" original_which_has_been_pgpd ");

(0)を返します。

}}

}

5 Answer


70


例外をキャッチするための基本的な経験則は、*例外_ifをキャッチすることです。

例外をログに記録してスタックに送出するだけの場合は、例外をキャッチしないでください。 これは意味がなく、コードを乱雑にします。

コードの特定の部分で障害が発生すると予想される場合、およびそれに対するフォールバックがある場合は、_Do_で例外をキャッチします。

もちろん、常にtry / catchブロックを使用する必要があるチェック済み例外の場合があります。この場合、他に選択肢はありません。 チェックされた例外があっても、あなたはきちんと記録して、できるだけきれいに扱ってください。


7


http://msdn.microsoft.com/ja-jp/library/ms173160(VS.80).aspx[例外と例外処理(C#プログラミングガイド)]

https://docs.microsoft.com/ja-jp/dotnet/articles/csharp/programming-guide/exceptions / index [例外と例外処理(C#プログラミングガイド)] _他のものはまだ最新のものですが(MSによる)_更新されたリンク。 _

http://msdn.microsoft.com/ja-jp/library/ms173162.aspx[Exception処理(C#プログラミングガイド)]


4


他の人が言ったように、あなたは例外を投げることができるそしてあなたが対処する準備ができているコードのまわりでtry catchブロックを使いたいです。

あなたの特定の例のために、File.DeleteはIOException、UnauthorizedAccessException、その他を含む多くの例外を投げることができます。 そのような状況でアプリケーションに何をさせたいですか。 ファイルを削除しようとしたが、他の誰かがそれを使用していると、IOExceptionが発生します。

{File.Delete(pgpdFilename "_archive")} catch(IOException){UtilityLogger.LogToFile( "ファイルは使用中です。上書きできませんでした。"); //アプリケーションにとって意味のある何か他のことをする//おそらくそれを別の名前か何かで保存する}

これが失敗すると、次にifブロックの外側で行うFile.Moveも失敗することに注意してください(ここでもIOException - ファイルが削除されなかったため、移動が失敗する原因となる) 。


3


私は、複数のエラーが発生する可能性があるすべてのメソッドやクラスにtry / catch /を使用するように教えられました。 データベーストランザクション、ファイルシステムI / O、ストリーミングなど コアロジックは通常try / catch / finallyを必要としません。

try / catch /の最後の大きな部分は複数のキャッチを持つことができるので、_very_特定のエラーを処理するための一連の例外ハンドラを作成したり、発生しないエラーをキャッチするための一般的な例外を使用できることです。

あなたの場合、あなたは良いFile.Existsを使っています、しかしそれらはおそらくFile.Existsが扱うことができない別のエラーを投げるかもしれないディスクに関する別の問題です。 はい、それはブール値のメソッドですが、ファイルがロックされていると言い、あなたがそれに書き込もうとするとどうなりますか? catchを使用すると、まれなシナリオを計画することができますが、try / catch / finallyを使用せずに、コードをまったく予期しない状況にさらす可能性があります。


1


他の人たちはかなりの数の優れた指針と参照を与えています。

私の意見は短いものです:それを使用するときそれが1つのことです、同等にまたはもっと重要なことはそれを正しく使用する方法です。

シモンズ:「それ」は、「例外を捉えようとしている」への言及です。