簡體   English   中英

嘗試在C#中捕獲語句

[英]Try, catch statement in C#

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

    }

將您的try / catch foreach 您沒有在帖子中進行解釋,但是我猜這是您遇到異常的地方。

這樣,將捕獲由其中的代碼引起的任何異常,並使循環繼續進行。

但是要小心-這兩行仍然不是異常安全的:

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

您還要考慮到這一點。

如果要顯示導致問題的確切文件/目錄是什么,則只需將異常toString設為toString ,例如:

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

如果toString沒有給您想要的輸出,請嘗試ex.Message 我總是只使用toString

編輯致謝肯·亨德森

使用任何類型的Stream ,都應將其放在using塊中。 垃圾收集器最終將Close流,但是這樣做的好習慣是, using完后, 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

您應該像這樣重新組織代碼:

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

范圍是此處的關鍵字。

您的嘗試抓住了整個森林。 這意味着當出現錯誤時,它將退出foreach。 您想要使try-catch靠近原點(即fInfo.Open(FileMode.Open) )。 這樣,在發生錯誤后,它可以繼續處理循環。

嘗試以下方法:

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


}

您還應該處理UnauthorizedAccessException ,如果無法訪問文件,則拋出該異常。

我可能正在監督某件事,因為解決方案很簡單,但是;

將Try-Catch塊放置在for每個文件的內部-如果無法訪問一個文件,則引發,捕獲異常,並在輸出錯誤消息后,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.");
    }

}

要了解無法訪問哪個文件,可以使用以下代碼段:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM