如果在 using 块中捕获异常,如何完全关闭文件?
How do I completely close a file if an exception is caught in a using block?
我有一个需要使用 FileStream 解析文件的应用程序。如果该文件被另一个进程使用,则 FileStream 初始化会抛出 IOException。我捕获了那个异常,告诉用户关闭文件,并且我提议让用户 "Retry." 不幸的是,即使用户关闭了文件,每次重试都会导致另一个 IOException 被抛出。为什么会发生这种情况,如何解决?
我在 using 块中有 FileStream,我用 FileShare.Read 打开文件。因为它在 using 块中,所以当抛出异常时它应该被处理掉,不是吗?
// Read all the lines in the file and save them to a List
try
{
using(FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
int count = 0;
do
{
byte[] buffer = new byte[RECORD_LENGTH];
count = fileStream.Read(buffer, 0, RECORD_LENGTH);
fileLines.Add(Encoding.ASCII.GetString(buffer));
} while(fileStream.CanRead && count > 0);
}
}
catch(IOException)
{
DialogResult result = MessageBox.Show("There was a problem reading the file:\n" + path +
"\nPlease ensure it is not used by another process and try again.", "File Error",
MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
if(result == DialogResult.Retry)
ParseFile(path);
else
return null;
}
我尝试过的事情:
- 递归调用方法(如上所示)
- 在 try 块之前放置一个标签,
goto
代替递归方法调用
- 添加一个
retryFlag
,在 catch 块中设置它,然后在 ParseFile(path)
catch 块之后调用 ]
这些解决方案中的每一个都以相同的结果结束:抛出 IOException 的永无止境的循环。
所以,直接回答问题:
您不需要,using 块将关闭流。在幕后使用块使用 try-catch-finally 并在最终块中调用 dispose 这将关闭您的流。
许多评论提出了其他好的观点,但我希望这能回答您的问题。
您可能想尝试的其他方法是简单地输出 exception.message 而不是用您自己的文件覆盖以关闭文件。您得到的 IOException 可能不是那个...
我有一个需要使用 FileStream 解析文件的应用程序。如果该文件被另一个进程使用,则 FileStream 初始化会抛出 IOException。我捕获了那个异常,告诉用户关闭文件,并且我提议让用户 "Retry." 不幸的是,即使用户关闭了文件,每次重试都会导致另一个 IOException 被抛出。为什么会发生这种情况,如何解决?
我在 using 块中有 FileStream,我用 FileShare.Read 打开文件。因为它在 using 块中,所以当抛出异常时它应该被处理掉,不是吗?
// Read all the lines in the file and save them to a List
try
{
using(FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
int count = 0;
do
{
byte[] buffer = new byte[RECORD_LENGTH];
count = fileStream.Read(buffer, 0, RECORD_LENGTH);
fileLines.Add(Encoding.ASCII.GetString(buffer));
} while(fileStream.CanRead && count > 0);
}
}
catch(IOException)
{
DialogResult result = MessageBox.Show("There was a problem reading the file:\n" + path +
"\nPlease ensure it is not used by another process and try again.", "File Error",
MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
if(result == DialogResult.Retry)
ParseFile(path);
else
return null;
}
我尝试过的事情:
- 递归调用方法(如上所示)
- 在 try 块之前放置一个标签,
goto
代替递归方法调用 - 添加一个
retryFlag
,在 catch 块中设置它,然后在ParseFile(path)
catch 块之后调用 ]
这些解决方案中的每一个都以相同的结果结束:抛出 IOException 的永无止境的循环。
所以,直接回答问题:
您不需要,using 块将关闭流。在幕后使用块使用 try-catch-finally 并在最终块中调用 dispose 这将关闭您的流。
许多评论提出了其他好的观点,但我希望这能回答您的问题。
您可能想尝试的其他方法是简单地输出 exception.message 而不是用您自己的文件覆盖以关闭文件。您得到的 IOException 可能不是那个...