C# close stream and delete file if something failed
I'm working with a file stream in C#. It's a storage cache, so if something goes bad writing the file (corrupted data, ...), I need to delete the file and rethrow the exception to report the problem. I'm thinking on how to implement it in the best way. My first attempt was:
Stream fileStream = null;
try
{
fileStream = new FileStream(GetStorageFile(),
FileMode.Create, FileAccess.Write, FileShare.Write);
//write the file ...
}
catch (Exception ex)
{
//Close the stream first
if (fileStream != null)
{
fileStream.Close();
}
//Delete the file
File.Delete(GetStorageFile());
//Re-throw exception
thr开发者_运维技巧ow;
}
finally
{
//Close stream for the normal case
if (fileStream != null)
{
fileStream.Close();
}
}
As you will see, if something goes bad writing the file, the fileStream will be closed twice. I know that it works, but I don't think that is the best implementation.
I think that I could remove the finally
block, and close the stream in the try
block, but I have posted this here because you guys are experts and I want to hear the voice of an expert.
If you put the fileStream in a using block you don't need to worry about closing it, and then just leave the cleaning up (deleting of the file in the catch block.
try
{
using (FileStream fileStream = new FileStream(GetStorageFile(),
FileMode.Create, FileAccess.Write, FileShare.Write))
{
//write the file ...
}
}
catch (Exception ex)
{
File.Delete(GetStorageFile());
//Re-throw exception
throw;
}
I believe what you want is this:
var fs = new FileStream(result.FilePath, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
I've used it with ASP.Net to have the web server return a result to a temp file that's on disk, but to make sure it's cleaned up after the web server finishes serving it to the client.
public static IActionResult TempFile(string tempPath, string mimeType, string fileDownloadName)
{
var fs = new FileStream(tempPath, FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose);
var actionResult = new FileStreamResult(fileStream: fs, contentType: mimeType)
{
FileDownloadName = fileDownloadName
};
return actionResult;
}
精彩评论