我有一个应用程序需要使用FileStream解析文件。如果该文件由另一个进程使用,则 FileStream 初始化将引发 IOException。我捕获了该异常,告诉用户关闭文件,并建议让用户"重试"。遗憾的是,每次重试都会导致引发另一个 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 块中,然后在 catch 块之后调用ParseFile(path)
如果标志打开
这些解决方案中的每一个都以相同的结果告终:IOExceptions的永无止境的循环被抛出。
所以,直接回答提出的问题:
您不需要,using 块将关闭流。 在幕后使用块利用尝试捕获最终,在最后块中,他们称之为 dispose 这将关闭您的流。
许多评论提出了其他好的观点,但我希望这能回答你的问题。
您可能想尝试的其他事情只是输出 exception.message,而不是用您自己的关闭文件覆盖。 你得到的IOException可能不是那个...