开发者

C# close stream and delete file if something failed

开发者 https://www.devze.com 2023-01-27 05:03 出处:网络
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 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;
        }
0

精彩评论

暂无评论...
验证码 换一张
取 消