【问题标题】:C# try and catchC# 尝试并捕捉
【发布时间】:2015-01-03 16:35:13
【问题描述】:

我刚刚注册了该网站,所以我可能弄错了。无论如何,如果找不到我的文件,我正在尝试使用 C# 中的 try 和 catch 来捕获我的文件。这是我目前的代码。重复我自己,我希望程序像它一样读取文件 - 但是如果找不到文件,我希望它给出一个错误,说“找不到文件”或类似的东西,而不仅仅是只是崩溃。 (我刚开始学习 C#)

感谢您的帮助!

string file = @"C:\Users\Henry\Desktop\Assessments\Programming and data structures\grades_multiple.txt";
try
{
    file = @"C:\Users\Henry\Desktop\Assessments\Programming and data structures\grades_multiple.txt";
}
catch
{
    Console.WriteLine("Could not find the file - grades_multiple.txt");
}            
//ARRAY for string lines
string[] Line = new string[6];
Line[0] = File.ReadLines(file).Skip(1).Take(1).First();

【问题讨论】:

  • 你可以尝试一个简单的字符串赋值。那不会抛出异常。它可能需要围绕您的 ReadallLines 声明,因为这可能会因各种原因而失败。

标签: c# file exception-handling try-catch


【解决方案1】:

你应该读取try catch里面的文件并catchFileNotFoundException,像这样:

var file = @"C:\Users\Henry\Desktop\Assessments\Programming and data structures\grades_multiple.txt";
string[] lines;
try
{
    lines = File.ReadAllLines(file);
}
catch (FileNotFoundException exnotfound)
{
    // file not found exception
}
catch (Exception ex)
{
    // handle other exceptions
}

【讨论】:

    【解决方案2】:

    您需要将容易出错的代码放在try 块内。

    try
    {
        Line[0] = File.ReadLines(file).Skip(1).Take(1).First();
    }
    catch(Exception ex)
    {
         Console.WriteLine("Could not find the file - grades_multiple.txt");
    }   
    

    顺便说一句,您可以通过首先使用File.Exists 方法检查文件是否存在来处理这种情况。不需要catch 例外。

    【讨论】:

      【解决方案3】:

      尝试 catch 是行不通的。 您正在尝试捕获更改字符串但不更改文件的代码行,因此该文件不需要存在,因此它 从不 抛出异常(在您的情况下) ,并且它永远不会捕捉到它。

      您应该围绕可能出错的代码:File.ReadLines

      你的代码会变成这样:

      string file = @"C:\Users\Henry\Desktop\Assessments\Programming and data structures\grades_multiple.txt";
      
      //can go wrong   
      try
      { 
           //ARRAY for string lines
           string[] Line = new string[6];
           Line[0] = File.ReadLines(file).Skip(1).Take(1).First();
      }
      //File.ReadLines is null
      catch
      {
           Console.WriteLine("Could not find the file - grades_multiple.txt");
      } 
      

      我还认为用 if 语句检查它是更好的做法,而不是在出错时捕获它:

      //if file exists
      if(File.Exists(file)) 
      {
          //ARRAY for string lines
          string[] Line = new string[6];
          Line[0] = File.ReadLines(file).Skip(1).Take(1).First();
      }
      //File does not exist
      else
      {
           Console.WriteLine("Could not find the file - grades_multiple.txt");
      } 
      

      【讨论】:

        【解决方案4】:

        如果可能的话,您应该尽量避免仅仅为了向用户显示消息或为了可以轻松测试的条件而引发异常。这主要是一个性能考虑,因为抛出异常是昂贵的。此外,除非您知道文件相对较小,否则将整个文件加载到内存中可能会影响性能..

        这是一个关于如何测试条件和处理它的快速原始示例。

        void Main()
        {
            var filePath ="C:\\TEST.DAT";
        
            if(!File.Exists(filePath)){ DisplayFileNotFoundError(filePath); }
        
            try
            {           
                var lines = GetFileLines(filePath);
                if(lines == null) { DisplayFileNotFoundError(filePath);}
        
                // do work with lines;
            }
            catch (Exception ex)
            {
                DisplayFileReadException(ex);
            }
        
        }
        
        void DisplayErrorMessageToUser(string filePath)
        {
            Console.WriteLine("The file does not exist");
        }
        
        void DisplayFileReadException(Exception ex){
            Console.WriteLine(ex.Message);
        }
        
        string[] GetFileLines(string filePath){
        
            if(!File.Exists(filePath)){ return null; }
        
            string[] lines;
            try
            {           
                lines = File.ReadLines(filePath);
                return lines;
            }
            catch (FileNotFoundException fnf){
                Trace.WriteLine(fnf.Message);
                return null;
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                throw ex;
            }
        }
        

        性能测试,FileNotFoundException 与 File.Exists

        void Main()
        {
            int max = 100000;
            long[] feSampling = new long[max];
            long[] exSampling = new long[max];
        
            String pathRoot ="C:\\MISSINGFILE.TXT";
            String path = null;
        
            Stopwatch sw = new Stopwatch();
            for (int i = 0; i < max; i++)
            {
                path = pathRoot + i.ToString();
                sw.Start();
                File.Exists(pathRoot);
                sw.Stop();
                feSampling[i] = sw.ElapsedTicks;
        
                sw.Reset();
            }
        
            StreamReader sr = null;
            sw.Reset();
            for (int i = 0; i < max; i++)
            {
                path = pathRoot + i.ToString();
                try
                {           
                    sw.Start();
                    sr = File.OpenText(path);
                }
                catch (FileNotFoundException)
                {
                    sw.Stop();
                    exSampling[i] = sw.ElapsedTicks;
                    sw.Reset();
        
                    if(sr != null) { sr.Dispose();}
                }
            }
        
            Console.WriteLine("Total Samplings Per Case: {0}", max);
            Console.WriteLine("File.Exists (Ticsk) - Min: {0}, Max: {1}, Mean: {2}", feSampling.Min(), feSampling.Max(), feSampling.Average ());
            Console.WriteLine("FileNotFoundException (Ticks) - Min: {0}, Max: {1}, Mean: {2}", exSampling.Min(), exSampling.Max(), exSampling.Average ());
        
        }
        

        【讨论】:

        • 当您处理磁盘操作时,无论如何您都必须捕获错误,并且与访问磁盘的成本相比,异常块的成本微不足道。为什么要有两条代码路径?
        • 这不是异常块的成本,而是它自己抛出异常的成本。在这种情况下,大部分 IO 操作的成本并不高,因为它是对主文件表的查找,而不是大量的查找。与其他一切一样,在选择一种方法而不是另一种方法时需要考虑许多因素,例如内部驱动器的速度或网络附加存储,也许更重要的是预计交易的数量。
        • 一次查找的成本远远超过抛出异常的成本。
        • 采样另有说明...每个案例的总采样数:100000 File.Exists (Ticsk) - 最小值:84,最大值:8183,平均值:89.24125 FileNotFoundException (Ticks) - 最小值:277,最大值:38695 , 均值:306.23548
        • 如果你继续测试同一个文件,它将会在缓存中并且不会有搜索。不过,这不是真实世界的表现。
        猜你喜欢
        • 1970-01-01
        • 2014-12-27
        • 1970-01-01
        • 1970-01-01
        • 2017-02-10
        • 1970-01-01
        • 1970-01-01
        • 2011-08-07
        • 1970-01-01
        相关资源
        最近更新 更多