尝试,在C#中捕获语句

时间:2013-05-02 13:07:00

标签: c# try-catch

我有以下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.");
        }

    }

8 个答案:

答案 0 :(得分:8)

将您的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

答案 1 :(得分: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
    }
}

答案 2 :(得分:1)

范围是此处的关键字。

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

答案 3 :(得分:1)

请改为尝试:

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;
}


}

答案 4 :(得分:0)

如果文件不可访问,您还应该处理引发的UnauthorizedAccessException

答案 5 :(得分:0)

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

将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.");
    }

}

答案 6 :(得分:0)

要知道哪些文件无法访问,您可以使用以下代码段:

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

答案 7 :(得分:0)

处理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;
    }