• 处理异常和错误


    处理异常和错误>

    if语句能检查错误,但必须在运行时。try/catch语句能在编译时检查异常。

    处理异常和错误>finally块的用途

    当打开文件,操作发生错误,虽然捕捉到异常,但资源没被释放。所以finally块可用来释放资源或其它。

    代码
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;

    namespace FinallyDemo
    {
        
    class Program
        {
            
    static void Main(string[] args)
            {
                
    const string filePath = @"C:\FinallyDemo.txt";
                FileStream fs
    =null;
                
    try
                {
                    Console.WriteLine(
    "开始执行文件的比较操作");
                    fs 
    = new FileStream(filePath, FileMode.CreateNew, FileAccess.ReadWrite);
                    
    byte[] bytes = Encoding.Default.GetBytes("这是一个字符串,将插入到文本文件");
                    
    //向流中写入指定的字节数组
                    fs.Write(bytes,0,bytes.Length);
                    
    //将缓冲区的内容存储到媒介并清除缓冲区。
                    fs.Flush();
                    
    //将流指针移到开头。
                    fs.Seek(0, SeekOrigin.Begin);
                    
    byte[] bytes2 = new byte[bytes.Length];
                    
    //
                    fs.Read(bytes2, 0, bytes.Length);
                    
    string str = Encoding.Default.GetString(bytes2);
                    Console.WriteLine(
    "从文件中读出的字符串为" + Environment.NewLine+str);
                }
                
    catch (IOException ex)                
                {
                    Console.WriteLine(
    "发生了文件处理的错误!" + ex.Message);
                }
                
    finally
                {
                    Console.WriteLine(
    "不论是否发生异常,都会执行finally到这里");
                    
    if (fs != null)
                    {
                        fs.Close();
                    }
                    Console.ReadLine();
                }
            }
        }
    }


    处理异常和错误>预定义异常的类

    描述:一个总BOSS异常类,引领两个帮派,一个是CLR自己定义好的异常类,另一个便是用户自定义的异常类。异常类嘛,总有些属性,这些属性提供了异常代码的位置,异常的描述信息啊等等。

    所有异常类的基类是System.Exception

    ·SystemException派生的预定义CLR异常类

    ·ApplicationException派生的用户自定义的应用程序异常类

    你可以查看下System.Exception的属性列表。

    一个例子:RunMethod调用Method2,Method2调用Method1。Method1抛出一个异常,Method2捕获异常,并将Method1的异常传递给RunMethod, RunMethod调用Exception类的属性,显示异常信息。

    显示异常信息
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.Collections;

    namespace ExceptionInfos
    {
        
    class Program
        {
            
    static void Main(string[] args)
            {
                Console.WriteLine(
    "显示额外的信息的结果为:");
                Console.WriteLine();
                RunMethod(
    true);
                Console.WriteLine(
    "不显示额外的信息的结果为:");
                Console.WriteLine();
                RunMethod(
    false);
                Console.ReadLine();
            }
            
    /// <summary>
            
    /// 显示当前异常和前一个异常的Exception属性信息。
            
    /// </summary>
            
    /// <param name="displayDetails"></param>
            static void RunMethod(bool displayDetails)
            {
                
    try
                {
                    Method2();
                }
                
    catch (Exception ex)
                {
                    Console.WriteLine(
    "当前的异常Message属性值为:{0}", ex.Message);
                    Console.WriteLine(
    "内部异常的Message属性值为:{0}", ex.InnerException.Message);
                    Console.WriteLine(
    "当前异常的Source属性值为:{0}", ex.Source);
                    Console.WriteLine(
    "内部异常的Source属性值为:{0}", ex.InnerException.Source);
                    Console.WriteLine(
    "当前异常StackTrace属性值为:{0}", ex.StackTrace);
                    Console.WriteLine(
    "内部异常的StackTrace属性值为:{0}", ex.InnerException.StackTrace);
                    Console.WriteLine(
    "当前异常TargetSite属性值为:{0}", ex.TargetSite);
                    Console.WriteLine(
    "内部异常的TargetSite属性值为:{0}", ex.InnerException.TargetSite);
                    Console.WriteLine(
    "当前异常HelpLink属性值为:{0}", ex.HelpLink);
                    Console.WriteLine(
    "内部异常的HelpLink属性值为:{0}", ex.InnerException.HelpLink);
                
    if (displayDetails)
                {
                    
    if (ex.InnerException.Data != null)
                    {
                        Console.WriteLine(
    "额外的异常信息是:");
                        
    foreach (DictionaryEntry de in ex.InnerException.Data)
                        {
                            Console.WriteLine(
    "键是:{0},值为{1}", de.Key, de.Value);
                        }
                    } 
                }
                }
            }
            
    /// <summary>
            
    /// 为Exception对象设置值,并直接抛出异常。
            
    /// </summary>
            static void Method1()
            {
                Exception ex 
    = new Exception("这是原始异常消息");

                    
    string s = "来自Method1的信息";
                    
    int i = 100;
                    DateTime dt 
    = DateTime.Now;
                    ex.Data.Add(
    "方法信息", s);
                    ex.Data[
    "整数值"= i;
                    ex.Data[
    "时间值"= dt;
                    
    throw ex;
            }
            
    /// <summary>
            
    /// 为内部异常的Data属性添加更多的信息。
            
    /// </summary>
            static void Method2()
            {
                
    try
                {
                    Method1();
                }
                
    catch (Exception ex)
                {
                    Exception e 
    = new Exception("这是来自Method2的异常信息", ex);
                    e.InnerException.Data[
    "附件信息"= "来自Method2的信息";
                    e.InnerException.Data.Add(
    "更多信息""来自Method2的更多信息");
                    
    throw e;
                }
            }
        }
    }


    处理异常和错误>处理和传递异常

    方法A,抛出一个异常A1,方法B,调用A,并且也跑出一个异常B1.如果希望在抛出B1的同时,也传递方法A抛出的异常A1,那么,需要将A1作为一个异常参数传递给B1,这样,跑出B1是,也抛出了A1.

    传递异常
    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace InnerException
    {
        
    class Program
        {
            
    static void Main(string[] args)
            {
                
    try
                {
                    A2();
                }
                
    catch (Exception ex)
                {
                    Console.WriteLine(
    "捕获的异常消息:{0}", ex.Message);
                    Console.WriteLine(
    "捕获的异常所传递的异常的消息:{0}", ex.InnerException.Message);
                    Console.ReadLine();
                }
            }
            
    //A1直接抛出一个异常
            static void A1()
            {            
                Exception ex 
    = new Exception("这是来自A1的异常消息");            
                
    throw ex;
            }
            
    //A2调用A1,并将A1抛出的异常保存到InnerException中。
            static void A2()
            {
                
    try
                {
                    A1();
                }
                
    catch(Exception e)
                {
                    Exception ex 
    = new Exception("这是来自A2的异常消息",e);
                    
    throw ex;
                }
            }
        }
    }


    处理异常和错误>从异常中恢复

    正在对两个文件同时执行写操作,对第一个文件的写操作已经完成,执行到对第二个文件的写操作时,抛出了异常。假设程序要求两个文件必须全部写入成功,只要有一个文件的写入失败,就应该回滚对第一个文件的写入。

    从异常中恢复
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    namespace RollbackException
    {
        
    class Program
        {
            
    static void Main(string[] args)
            {
                
    try
                {
                    WriteFile();
                }
                
    catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.ReadLine();
                }
            }
            
    /// <summary>
            
    /// 异常恢复的示例,假定有两个文件,只要有一个写入失败,就全部回滚。
            
    /// </summary>
            static void WriteFile()
            { 
                
    const string filePath1=@"C:\RoolbackException1.txt";
                
    const string filePath2=@"C:\RoolbackException2.txt";
                FileStream fs 
    = null;
                FileStream fs1 
    = null;
                
    long fsPosition = 0;
                
    long fs1Position = 0;
                
    try
                { 
                    
    string str = "这是需要被写入到两个文件中的字符串"
                    
    byte[] bytes = Encoding.Default.GetBytes(str.ToCharArray());
                    fs 
    = new FileStream(filePath1, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    
    //先将流位置移到文件尾部
                    fs.Seek(0, SeekOrigin.End);
                    
    //获取Position,以用于恢复
                    fsPosition = fs.Position;
                    
    //写入指定的字节数组
                    fs.Write(bytes, 0, bytes.Length);
                    
    //写入磁盘清除缓冲区
                    fs.Flush();
                    fs1 
    = new FileStream(filePath2, FileMode.CreateNew, FileAccess.ReadWrite);
                    fs1.Seek(
    0, SeekOrigin.End);
                    fs1Position 
    = fs1.Position;
                    fs1.Write(bytes, 
    0, bytes.Length);
                    fs1.Flush();
                }
                
    //catch后面并没有加任何表达式,这是可行的,这表示获取所有与CLS兼容或不兼容的异常。
                
    //一旦发生错误,则将文件恢复到写入前的状态。
                catch
                {
                    
    if (fs != null)
                    {
                        fs.Position 
    = fsPosition; 
                        fs.SetLength(fsPosition);
                    }
                    
    if (fs1 != null)
                    {
                        fs1.Position 
    = fs1Position;
                        fs1.SetLength(fs1Position);
                    }
                    
    throw;
                }
                
    //执行文件关闭操作。不管有没有引发异常。
                finally
                {
                    
    if (fs != null)
                    {
                        fs.Close();
                    }
                    
    if (fs1 != null)
                    {
                        fs1.Close();
                    }
                }
            }
        }
    }

    处理异常和错误>设计自己的异常

    上面“从异常中恢复”,是简单地将系统异常抛出,现在设计抛出一个自定义的WriteFailedException类型的异常。

    Program.cs
    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace CustomException
    {
        
    class Program
        {
            
    static void Main(string[] args)
            {
                
    try
                {
                    WriteFile();
                }
                
    catch (WriteFailedException ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.ReadLine();
                }
            }
            
    static void WriteFile()
            {
                
    throw new WriteFailedException();
            }
        }
    }
    WriteFailedException.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace CustomException
    {
        
    /// <summary>
        
    /// 自定义异常类的示例
        
    /// </summary>
        public class WriteFailedException:ApplicationException
        {
            
    public WriteFailedException()
                :
    base("对两个文件的操作产生了一个异常")
            { 
            }
            
    public WriteFailedException(string Message)
                : 
    base(Message)
            { }
            
    public WriteFailedException(string Message, Exception inner)
                : 
    base(Message, inner)
            { }
        }
    }



    合乎自然而生生不息。。。
  • 相关阅读:
    160-13. 罗马数字转整数
    159-118. 杨辉三角
    158-190. 颠倒二进制位
    157-461. 汉明距离
    156-412. Fizz Buzz
    155-278. 第一个错误的版本
    154-108. 将有序数组转换为二叉搜索树
    153-101. 对称二叉树
    152-234. 回文链表
    秒杀程序架构演进
  • 原文地址:https://www.cnblogs.com/samwu/p/1849938.html
Copyright © 2020-2023  润新知