我有一个递归函数,用于散列目录和所有子目录。我使用的是SHA1,但问题并非如此。我的问题是它需要一个字节数组(可以理解)。所以我采用我的字节数组列表List<byte[]> byteFile
并用bytfile.selectmany(x=>x).toarry()
展平它。当我压扁我的阵列时出现问题,因为在VS调试中我得到内存不足异常。在耗尽大约220KB的程序之前扁平化。在展平之后(当没有在vs环境中运行时)编程消耗1.09GB。为什么扁平化这个字节数组列表会消耗这么多内存?如何减少内存占用。
以下是我使用
的代码 private static byte[] GetGameHash(string path)
{
DirectoryInfo dir = new DirectoryInfo(path);
List<byte[]> byteFile = new List<byte[]>();
var dirs = dir.EnumerateDirectories();
ReadFolderContents(dir, ref byteFile);
//byte[] input = byteFile.SelectMany(x => x).ToArray();
SHA1 mSha1 = new SHA1CryptoServiceProvider();
mSha1.Initialize();
byte[] hash = mSha1.ComputeHash(byteFile.SelectMany(x=>x).ToArray());
mSha1.Dispose();
byteFile.Clear();
return hash;
}
private static void ReadFolderContents(DirectoryInfo directory, ref List<byte[]> files)
{
var dirFiles = directory.EnumerateFiles();
foreach (var file in dirFiles)
files.Add(System.IO.File.ReadAllBytes(file.FullName));
var directories = directory.EnumerateDirectories();
foreach (var dir in directories)
ReadFolderContents(dir, ref files);
}
答案 0 :(得分:7)
如图所示的程序获取所有目录中所有文件的全部内容,并将其放入字节数组中。如果你有十亿字节的文件,那么你将得到一个十亿字节的数组。
这是解决这个问题的可怕方法。如果您尝试对超过一小部分字节的内容进行哈希处理,则应该对流进行哈希处理,而不是字节。
退后一步。您真的尝试使用此哈希解决的问题是什么?让我们专注于这里真正的问题;赔率是好的,你的策略存在一些根本性的错误,而不仅仅是内存不足这一事实。
那就是说,你写的这个简短的节目还有很多其他的问题。为什么直接拨打Dispose
而不是使用using
,这是惯用的?你为什么使用ref
?列表已经是引用类型。为什么bytefile
在超出范围之前立即被清除?当你看来所有你需要的是一个序列时,你为什么首先将它作为一个列表来实现呢?关于这个程序的一切都说&#34;不必要地使用内存&#34;到处都是,所以你使用大量内存对我来说并不奇怪。等等。您的组织中是否有C#专家可以审核您的工作?
答案 1 :(得分:1)
您正在将所有文件读入内存,并计算所有文件的哈希值。 您在内存中同时拥有所有文件。这就是为什么你的内存不足。
为什么不逐个读取文件并为每个文件计算哈希值,将单个哈希值存储在哈希值列表中,最后在哈希值上计算哈希值?