C# 异常代码,或检测到“文件已存在”类型异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12389599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Exception codes, or detecting a "file already exists" type exception
提问by GazTheDestroyer
In trying to answer this question, I was surprised to discover that attempting to create a new file when that file already exists does not throw a unique exception type, it just throws a generic IOException.
在尝试回答这个问题时,我惊讶地发现当该文件已经存在时尝试创建一个新文件不会抛出唯一的异常类型,它只会抛出一个通用的IOException.
I am therefore left wondering how to determine if the IOExceptionis the result of an existing file, or some other IO error.
因此,我想知道如何确定这IOException是现有文件的结果,还是其他一些 IO 错误。
The exception has an HResult, but this property is protected, and thus unavailable to me.
异常有一个 HResult,但这个属性是受保护的,因此我无法使用。
The only other way I can see is to pattern match the message string which feels awful.
我能看到的唯一另一种方法是模式匹配感觉很糟糕的消息字符串。
example:
例子:
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?
}
采纳答案by jgauffin
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"); // =)
}
Won't work for temp files etc which might have been deleted again.
不适用于可能已再次删除的临时文件等。
回答by Vytalyi
You should use
你应该使用
FileMode.Create
instead of
代替
FileMode.CreateNew
It will override a file if its already exists.
如果文件已经存在,它将覆盖文件。
回答by Danny van der Kraan
You can't. Unfortunatly IOExceptions are not further specified for some reason beyond my comprehension in the .NET framework.
你不能。不幸的是 IOExceptions 由于某种原因超出了我在 .NET 框架中的理解,没有进一步指定。
But in case of creating a new file it is common practice to check if the file exists first. Like so:
但是在创建新文件的情况下,通常的做法是先检查文件是否存在。像这样:
try
{
if (File.Exists("C:\Test.txt"))
{
//write file
using (var stream = new FileStream("C:\Test.txt", FileMode.CreateNew))
using (var writer = new StreamWriter(stream))
{
//The actual writing of file
}
}
}
catch (IOException ex)
{
//how do I know this is because a file exists?
Debug.Print(ex.Message);
}
Perhaps not the answer you were looking for. But, c'est ca.
也许不是您要找的答案。但是,c'est ca。
回答by Joe
It's not 100% foolproof (there are other reasons for an IOException), but you can at least exclude all derived exception types:
这不是 100% 万无一失(IOException 还有其他原因),但您至少可以排除所有派生的异常类型:
try
{
...
}
catch(IOException e)
{
if (e is UnauthorizedAccessException) throw;
if (e is DirectoryNotFoundException) throw;
if (e is PathTooLongException) throw;
// etc for other exceptions derived from IOException
... assume file exists
}
or the equivalent:
或等价物:
try
{
...
}
catch(UnauthorizedAccessException)
{
throw;
}
catch(DirectoryNotFoundException)
{
throw;
}
catch(PathTooLongException)
{
throw;
}
catch(IOException e)
{
... assume file exists
}
As for the linked question, I'd just check for existence, prompt the user to overwrite, then use OpenOrCreateto overwrite if it exists. I think most apps work this way even if there is a theoretical risk of overwriting a file that's created just at the wrong moment.
至于链接的问题,我只是检查是否存在,提示用户覆盖,OpenOrCreate如果存在则使用覆盖。我认为大多数应用程序都以这种方式工作,即使理论上存在覆盖在错误时刻创建的文件的风险。
回答by ThunderGr
You can place this condition in your catch statement for IOException: if(ex.Message.Contains("already exists")) { ... }. It is a hack, but it will work for all cases that a file exists, even temporary files and such.
您可以将此条件放在 IOException: 的 catch 语句中if(ex.Message.Contains("already exists")) { ... }。这是一个 hack,但它适用于文件存在的所有情况,甚至是临时文件等。
回答by Arithmomaniac
To modify @jgauffin, in C# 6, you can use the File.Existsinside of the whenclause to avoid entering the catchblock and thus behaving more like an actual dedicated exception:
要修改@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"))
{
//...
}
回答by yurish
Edit: there is another Hresult that is used when file already exists: 0x800700B7 (-2147024713)"Cannot create a file when that file already exists". Updated the code sample.
编辑:当文件已存在时使用另一个 Hresult:0x800700B7 (-2147024713)“当该文件已存在时无法创建文件”。更新了代码示例。
When you try to create a new file and it already exists IOException will have Hresult = 0x80070050 (-2147024816).
当您尝试创建一个新文件并且它已经存在时 IOException 将具有Hresult = 0x80070050 (-2147024816).
So you code could look like this:
所以你的代码可能是这样的:
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.
}
}
回答by S?ren L?vborg
In C# 6 and later:
在 C# 6 及更高版本中:
const int WARN_WIN32_FILE_EXISTS = unchecked((int)0x80070050);
try
{
...
}
catch (IOException e) when (e.HResult == WARN_WIN32_FILE_EXISTS)
{
...
}
... or just when (e.HResult == -2147024816), if you're going for "quick and impenetrable". ;-)
...或者只是when (e.HResult == -2147024816),如果您要“快速且难以理解”。;-)
(FWIW, the Windows-centric error code has been faithfully copied by Mono and also works on Mac/Linux.)
(FWIW,以 Windows 为中心的错误代码已被 Mono 忠实地复制,并且也适用于 Mac/Linux。)

