异常代码,或检测"文件已存在"类型异常

Gaz*_*yer 16 c# exception ioexception

在试图回答这个问题时,我惊讶地发现,当该文件已经存在时尝试创建一个新文件不会抛出一个唯一的异常类型,它只会抛出一个泛型IOException.

因此,我想知道如何确定它IOException是现有文件的结果还是其他一些IO错误.

该异常具有HResult,但此属性受到保护,因此对我无法使用.

我能看到的另一种方式是模式匹配感觉糟糕的消息字符串.

例:

try
{
    using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
    using (var writer = new StreamWriter(stream))
    {
        //write file
    }
}
catch (IOException e)
{
    //how do I know this is because a file exists?
}
Run Code Online (Sandbox Code Playgroud)

jga*_*fin 9

try
{
    using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
    using (var writer = new StreamWriter(stream))
    {
        //write file
    }
}
catch (IOException e)
{
    var exists = File.Exists(@"C:\Text.text"); // =)
}
Run Code Online (Sandbox Code Playgroud)

不适用于可能已被删除的临时文件等.

  • 这不是确定性的方式:在抛出异常之后但在catch块中检查之前,可以删除文件. (5认同)
  • 这就是为什么我说“不适用于可能已再次删除的临时文件等” (2认同)

Ari*_*iac 7

要修改 @jgauffin,在 C# 6 中,您可以使用子句File.Exists内部when来避免进入catch块,从而表现得更像实际的专用异常

try
{
    using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
    using (var writer = new StreamWriter(stream))
    {
        //write file
    }
}
catch (IOException e) when (File.Exists(@"C:\Text.text"))
{
   //...
}
Run Code Online (Sandbox Code Playgroud)


Thu*_*rGr 5

您可以将此条件放在您的catch语句中以获取IOException : if(ex.Message.Contains("already exists")) { ... }. 这是一个hack,但它适用于文件存在的所有情况,甚至是临时文件等.

  • 非英语文化除外。 (2认同)

yur*_*ish 5

编辑:当文件已存在时使用另一个 Hresult:0x800700B7 (-2147024713)“当该文件已存在时无法创建文件”。更新了代码示例。


当您尝试创建一个新文件并且它已经存在时 IOException 将具有Hresult = 0x80070050 (-2147024816).

所以你的代码可能是这样的:

try
{
    using (var stream = new FileStream("C:\\Test.txt", FileMode.CreateNew))
    using (var writer = new StreamWriter(stream))
    {
        //write file
    }
}
catch (IOException e)
{
    if (e.HResult == -2147024816 || 
        e.HResult == -2147024713)
    {
        // File already exists.
    }
}
Run Code Online (Sandbox Code Playgroud)

  • [更多信息](/sf/ask/3246633841/#46381756) (2认同)