在System.IO中有一个功能: string File.ReadAllText(string path);
我正在尝试编写一个调用File.ReadAllText的函数,处理所有可能的异常并返回true / false并存储错误消息。
我拥有的是:
public static class FileNoBS
{
public static bool ReadAllText( string path, out string text, out string errorMessage )
{
errorMessage = null;
text = null;
bool operationSuccessful = false;
try
{
text = System.IO.File.ReadAllText( path );
operationSuccessful = true;
}
catch ( ArgumentNullException e )
{
errorMessage = "Internal software error - argument null exception in FileNoBs.ReadAllText\nMessage: " + e.Message;
}
catch ( ArgumentException e )
{
errorMessage = "Internal software error - path is a zero-length string, contains only white space, or contains one or more invalid characters as defined by InvalidPathChars in FileNoBs.ReadAllText.\nMessage: " + e.Message;
}
catch ( PathTooLongException e )
{
errorMessage = "The specified path was too long.\nMessage: " + e.Message;
}
catch ( DirectoryNotFoundException e )
{
errorMessage = "The specified directory was not found.\nMessage: " + e.Message;
}
catch ( FileNotFoundException e )
{
errorMessage = "The file specified in path was not found.\nMessage: " + e.Message;
}
catch ( IOException e )
{
errorMessage = "An I/O error occurred while opening the file.\nMessage: " + e.Message;
}
catch ( UnauthorizedAccessException e )
{
errorMessage = @"UnauthorizedAccessException
path specified a file that is read-only.
-or-
This operation is not supported on the current platform.
-or-
path specified a directory.
-or-
The caller does not have the required permission.\nMessage: " + e.Message;
}
catch ( NotSupportedException e )
{
errorMessage = "path is in an invalid format.\nMessage: " + e.Message;
}
catch ( SecurityException e )
{
errorMessage = "You do not have the required permission.\nMessage: " + e.Message;
}
return operationSuccessful;
}
}
我不明白控制流如何与返回值的函数相关联。 假设UnauthorizedAccessException被捕获,errorMessage被设置为
errorMessage = "You do not have the required permission..."
我知道最终每次都会执行,但编译器不会让我在finally块中返回。那么我的回归是否会达到?
另一个问题是如何在遵循官方指南的同时简化此操作: “一般来说,你应该只抓住你知道如何从中恢复的例外情况。”
我害怕在File类(Move,Copy,Delete,ReadAllText,WriteAllText)和Directory类中执行我需要的所有函数,并执行所有这些长代码块,以捕获我不关心的所有异常并没有抓到太多因为微软说这很糟糕。
谢谢。
编辑:我得到的评论不是处理异常这是“别的东西”。
我是我的代码的客户端,我想做这样的事情:
if ( !FileNoBS.ReadAllText( path, text, errorMessage ) ) {
MessageBox.Show( errorMessage );
return;
}
// continue working with all errors taken care of - don't care for whatever reason file wasn't opened and read, user is notified and I am moving on with my life
答案 0 :(得分:4)
由于try块或catch块中没有返回,因此将返回您的返回。
通常,您只想捕获预期可能发生的异常并有办法处理它们。例如,您可能希望处理从给定路径找不到的文件并返回默认文件。您应该允许其他异常不被捕获,因此您知道发生了意外事件而不是通过捕获所有异常来隐藏它。
答案 1 :(得分:2)
正如我在评论中所说,你最好在更高级别处理异常并简单地显示异常消息,而不是手动设置每条消息。我认为在这种情况下,来自异常的消息将具有足够的描述性。
public static class FileNoBS
{
public static string ReadAllText(string path)
{
return System.IO.File.ReadAllText( path );
}
}
然后在应用程序的某个更高级别使用它。我通常有一个通用处理程序来处理所有应用程序异常并记录它们并在必要时显示一个消息框。
try
{
var text = FileNoBS.ReadAllText("file.ext");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
答案 2 :(得分:1)
除了捕获异常之外,您应该尽量避免导致这些异常被抛出的情况。在您的情况下,您应该在调用ReadAllText
File.Exists(path)
应在输入源自的地方执行这些测试。也就是说,如果用户输入它们,请在使用它们之前对其进行验证。如果他们来自数据库或其他地方在使用前验证。如果它不是用户输入,则它们都是系统错误的指示,应该被视为这样,而不是用户应该担心的事情。
安全性异常可能在某种程度上难以在前面进行测试,在许多情况下,获得违规是非常特殊的,因此完全可以获得异常。它当然不应该使程序崩溃,而是应该向用户发送错误消息(如果它是基于用户输入的,如果是系统生成的数据导致这种情况,那么它是系统错误的标识,应该在代码级别修复)。在调用发生时执行此操作通常比在某些库方法中更合适。
对于IOExceptions
,它们可以放入两个桶中。可恢复一次(通常是重试)并且不可恢复一次。至少为用户提供有关异常的反馈,因此用户可以选择重试。
应该成为纠错逻辑一部分的一般规则是永远不要在系统周围浮动无效数据。确保所有对象都管理不变量(工具可用于此,例如代码协定)。收到用户(或其他系统)收到的无效输入,而不是导致异常的输入。
如果您进行所有输入验证并仍然具有例如。 ArgumentNullException
然后指出程序逻辑中的错误,您希望在发布错误之前能够在测试中轻松找到并纠正错误。你不应该试图掩盖这个错误。
答案 3 :(得分:0)
没有发生其他错误,是的。
我最后补充说:
catch (Exception e)
{
errormessage = "An unexpected error has occured.";
}
return operationSuccessful;
尽管如此,即使您收到错误,也会始终返回成功。我不确定这是不是你想要的,或者你的变量是否被严格命名。
答案 4 :(得分:0)
如果代码中有任何异常,则会在程序结束之前将其返回之前调用return语句。
我建议使用高级异常类型放置一个异常处理程序,例如' Exception'键入自己,并打印或记录异常消息。在每个方法中指定这么多的异常处理程序会占用你应该在方法本身中投入的大量精力。
try
{
return ReadAllText("path", "text", "error");
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
return false;
因此,如果调用该方法,它将立即返回,否则将打印/记录异常,并且该方法将返回false。
但是,在某些情况下,您可以提及几个或几个显式异常处理程序,您认为它们会有所帮助。
答案 5 :(得分:-2)
是它将返回值。
但是,最好在finally语句中处理return
值。
如果在任何情况下你想要返回operationSuccessful值,那么在catch块之后写下finally块,如下所示,
finally
{
return operationSuccessful;
}