【问题标题】:Try, catch statement in C#尝试,C# 中的 catch 语句
【发布时间】:2013-05-02 21:33:08
【问题描述】:

我有以下 C# 代码用于计算某个用户指定目录中每个文件的哈希值。关键是它可以正常工作,直到遇到无法访问的文件。当它发现这样的东西时,它只是抛出一条错误消息并退出程序。我想要它做的是,抛出一条带有无法访问的文件名的错误消息,写下访问该文件时出错,然后继续使用目录中的其他文件执行程序。如果有人可以帮助我编辑我的代码并实现这些目标,我会很高兴。

    private void SHA256Directory(string directory)
    {
        try
        {
            SHA256 DirectorySHA256 = SHA256Managed.Create();
            byte[] hashValue;

            DirectoryInfo dir = new DirectoryInfo(directory);
            FileInfo[] files = dir.GetFiles();

            foreach (FileInfo fInfo in files)
            {
                FileStream fStream = fInfo.Open(FileMode.Open);
                fStream.Position = 0;
                hashValue = DirectorySHA256.ComputeHash(fStream);

                Console.WriteLine(fInfo.Name);
                Miscellaneous.ByteArrayToHex(hashValue);
                Miscellaneous.ByteArrayToBase64(hashValue);
                Console.WriteLine();

                fStream.Close();
            }

            return;
        }
        catch(DirectoryNotFoundException)
        {
            Console.WriteLine("Error: The directory specified could not be found.");
        }
        catch(IOException)
        {
            Console.WriteLine("Error: A file in the directory could not be accessed.");
        }
        catch(ArgumentNullException)
        {
            Console.WriteLine("Error: The argument cannot be null or empty.");
        }

    }

【问题讨论】:

    标签: c# try-catch


    【解决方案1】:

    将您的 try/catch 移到 foreach 中。你没有在你的帖子中解释,但我猜这就是你遇到异常的地方。

    这样做,任何由其中的代码引起的异常都会被捕获并允许循环继续。

    不过要小心——这两行仍然不是异常安全的:

    DirectoryInfo dir = new DirectoryInfo(directory);
    FileInfo[] files = dir.GetFiles();
    

    您也需要考虑这一点。

    如果您希望它显示究竟是什么文件/目录导致了问题,只需toString 异常,例如:

    catch(DirectoryNotFoundException ex)
    {
        Console.WriteLine("Error: The directory specified could not be found: " + ex.toString());
    }
    

    如果toString 没有为您提供所需的输出,请尝试ex.Message。不过,我总是只使用toString

    编辑归功于Ken Henderson

    当使用任何类型的Stream 时,您应该将它放在using 块中。垃圾收集器最终会Close 流,但这样做是一种很好的做法,因为using 块会在您使用完流后立即关闭它:

    using (FileStream fStream = fInfo.Open(FileMode.Open)) 
    {
        fStream.Position = 0;
        hashValue = DirectorySHA256.ComputeHash(fStream);
    
        Console.WriteLine(fInfo.Name);
        Miscellaneous.ByteArrayToHex(hashValue);
        Miscellaneous.ByteArrayToBase64(hashValue);
        Console.WriteLine();
    } // No need for fStream.Close() any more, the using block will take care of it for you
    

    【讨论】:

    • 不认为这值得另一个答案,但不要忘记您应该在打开流时使用 using 语句或 try catch 块的 finally 块以确保流是关闭/处置
    【解决方案2】:

    你应该像这样重新组织你的代码:

    private void SHA256Directory(string directory)
    {
        try
        {
            DirectoryInfo dir = new DirectoryInfo(directory);
            FileInfo[] files = dir.GetFiles();
    
            foreach (FileInfo fInfo in files)
            {
                try
                {
                    SHA256 DirectorySHA256 = SHA256Managed.Create();
                    byte[] hashValue;
    
                    FileStream fStream = fInfo.Open(FileMode.Open);
                    fStream.Position = 0;
                    hashValue = DirectorySHA256.ComputeHash(fStream);
    
                    Console.WriteLine(fInfo.Name);
                    Miscellaneous.ByteArrayToHex(hashValue);
                    Miscellaneous.ByteArrayToBase64(hashValue);
                    Console.WriteLine();
    
                    fStream.Close();
                }
                catch (...)
                {
                    // Handle other exceptions here. Through finfo, you can
                    // access the file name
                }
            }
        }
        catch (...)
        {
            // Handle directory/file iteration exceptions here
        }
    }
    

    【讨论】:

      【解决方案3】:

      Scope 是这里的关键字。

      你的 try catch 包围了整个 foreach。这意味着当出现错误时,它将退出foreach。您想让 try-catch 更接近原点(即fInfo.Open(FileMode.Open))。这样,在出错后它可以继续处理循环。

      【讨论】:

        【解决方案4】:

        试试这个:

        private void SHA256Directory(string directory)
        {
            SHA256 DirectorySHA256 = SHA256Managed.Create();
            byte[] hashValue;
        
            DirectoryInfo dir = new DirectoryInfo(directory);
            FileInfo[] files = dir.GetFiles();
        
            foreach (FileInfo fInfo in files)
            {
                try
                {
                    FileStream fStream = fInfo.Open(FileMode.Open);
                    fStream.Position = 0;
                    hashValue = DirectorySHA256.ComputeHash(fStream);
        
                    Console.WriteLine(fInfo.Name);
                    Miscellaneous.ByteArrayToHex(hashValue);
                    Miscellaneous.ByteArrayToBase64(hashValue);
                    Console.WriteLine();
        
                    fStream.Close();
                }
                catch(DirectoryNotFoundException)
                {
                    Console.WriteLine("Error: The directory specified could not be found.");
                }
                catch(IOException)
                {
                    Console.WriteLine("Error: A file in the directory could not be accessed.");
                }
                catch(ArgumentNullException)
                {
                    Console.WriteLine("Error: The argument cannot be null or empty.");
                }
            }
            return;
        }
        
        
        }
        

        【讨论】:

        • 好吧,dir.GetFiles 中可能存在您现在没有发现的例外情况。
        • 这是真的。我认为当他无法访问文件时,他更关心处理错误。出于这个原因,我会选择你的解决方案而不是我的解决方案。
        • 把内部try / catch(旨在从打开文件中捕获错误),仅围绕file.open
        【解决方案5】:

        您还应该处理在文件不可访问时抛出的UnauthorizedAccessException

        【讨论】:

          【解决方案6】:

          可能是我在监督某些事情,因为解决方案相当简单,但是;

          将处理访问问题的 Try-Catch 块放置在 for each 中 - 如果一个文件不可访问,则抛出异常并捕获该异常,并在打印错误消息后 foreach 继续处理列表中的下一个文件.

          private void SHA256Directory(string directory)
          {
              try
              {
                  SHA256 DirectorySHA256 = SHA256Managed.Create();
                  byte[] hashValue;
          
                  DirectoryInfo dir = new DirectoryInfo(directory);
                  FileInfo[] files = dir.GetFiles();
          
                  foreach (FileInfo fInfo in files)
                  {
                     try
                     {
          
          
                         FileStream fStream = fInfo.Open(FileMode.Open);
                         fStream.Position = 0;
                         hashValue = DirectorySHA256.ComputeHash(fStream);
          
                         Console.WriteLine(fInfo.Name);
                         Miscellaneous.ByteArrayToHex(hashValue);
                         Miscellaneous.ByteArrayToBase64(hashValue);
                         Console.WriteLine();
          
                         fStream.Close();
                      }
                      catch(IOException)
                      {
                         Console.WriteLine("Error: A file in the directory could not be accessed.");
                      }
                  }
          
                  return;
              }
              catch(DirectoryNotFoundException)
              {
                  Console.WriteLine("Error: The directory specified could not be found.");
              }
              catch(ArgumentNullException)
              {
                  Console.WriteLine("Error: The argument cannot be null or empty.");
              }
          
          }
          

          【讨论】:

            【解决方案7】:

            要知道哪个文件不可访问,您可以使用以下 sn-p :

            catch(FileNotFoundException ex)
            {
            Console.writeLine("File not found " + ex.FileName);
            }
            

            【讨论】:

              【解决方案8】:

              处理 UnauthorizedAccessException 并将 try 语句放入 foreach 语句中。

              private  void SHA256Directory(string directory)
                  {
                      SHA256 DirectorySHA256 = SHA256Managed.Create();
                      byte[] hashValue;
              
                      DirectoryInfo dir = new DirectoryInfo(directory);
                      FileInfo[] files = dir.GetFiles();
              
                      foreach (FileInfo fInfo in files)
                      {
                          try
                          {
                              FileStream fStream = fInfo.Open(FileMode.Open);
                              fStream.Position = 0;
                              hashValue = DirectorySHA256.ComputeHash(fStream);
              
                              Console.WriteLine(fInfo.Name);
                              Miscellaneous.ByteArrayToHex(hashValue);
                              Miscellaneous.ByteArrayToBase64(hashValue);
                              Console.WriteLine();
              
                              fStream.Close();
                          }
                          catch (DirectoryNotFoundException)
                          {
                              Console.WriteLine("Error: The directory specified could not be found.");
                          }
                          catch (UnauthorizedAccessException)
                          {
                              Console.WriteLine("Error: A file in the directory could not be accessed.in {0}", fInfo.Name);
                          }
                          catch (ArgumentNullException)
                          {
                              Console.WriteLine("Error: The argument cannot be null or empty.");
                          }
                          catch (IOException)
                          {
                              Console.WriteLine("Error:IOExcepiton occured");
                          }
              
                      }
              
                      return;
                  }
              

              【讨论】:

                猜你喜欢
                • 2012-05-22
                • 1970-01-01
                • 2015-09-13
                • 1970-01-01
                • 2010-10-29
                • 2016-03-05
                • 1970-01-01
                • 2014-12-22
                相关资源
                最近更新 更多