我有以下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.");
}
}
答案 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
。
使用任何类型的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;
}