Aki*_*ake 1 c# linq directory file duplicates
我目前正在编写一个程序,该程序使用来自用户的给定参数从各种来源大量下载图像.
我的问题是我不希望重复发生.我应该指出,我一次处理大量下载100次(不是那么大),并且每个文件都有不同的名称,因此只需按文件名搜索就行不通,我需要检查哈希值.
无论如何,这是我已经找到的:
Directory.GetFiles(FullPath)
.Select(f => new
{
FileName = f,
FileHash = Encoding.UTF8.GetString(new SHA1Managed().ComputeHash(new FileStream(f, FileMode.Open, FileAccess.Read)))
})
.GroupBy(f => f.FileHash)
.Select(g => new { FileHash = g.Key, Files = g.Select(z => z.FileName).ToList() })
.SelectMany(f => f.Files.Skip(1))
.ToList()
.ForEach(File.Delete);
Run Code Online (Sandbox Code Playgroud)
我的问题是,在"File.Delete"行中,我得到了这个着名的错误,该文件已被其他进程使用.我认为这是因为上面的代码没有办法在删除文件之前关闭它用于获取FileHash的FileStream,但我不知道如何解决这个问题,任何想法?
我还应该指出我已经尝试过其他解决方案,比如这个(没有linq):https://www.bhalash.com/archives/13544802709 用删除一个替换打印功能,没有错误但不起作用.
在此先感谢,我可以提供所需的任何其他信息!:)
昭武
您忘了丢弃FileStream
,因此文件仍然打开,直到GC收集对象.
您可以将Select
子句替换为:
.Select(f => {
using (var fs = new FileStream(f, FileMode.Open, FileAccess.Read))
{
return new
{
FileName = f,
FileHash = BitConverter.ToString(SHA1.Create().ComputeHash(fs))
});
}
})
Run Code Online (Sandbox Code Playgroud)
别NOT使用Encoding.UTF8
以编码任意字节(其中散列是),作为其结果可能是一个无效的UTF8序列.使用BitConverter.ToString
,如果你一定要,或者更好的是:找不涉及字符串的方式不同.
例如,你可以写:
.Select(f => {
// Same as above, but with:
// FileHash = SHA1.Create().ComputeHash(fs)
})
.GroupBy(f => f.FileHash, StructuralComparisons.StructuralEqualityComparer)
Run Code Online (Sandbox Code Playgroud)
您可以使用更好的方法:您可以先按大小对文件进行分组,并仅在存在多个具有相同大小的文件时计算散列.当重复次数不多时,这应该会更好.
归档时间: |
|
查看次数: |
2791 次 |
最近记录: |