首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >排序和删除重复图像文件

排序和删除重复图像文件
EN

Code Review用户
提问于 2021-04-02 18:35:51
回答 1查看 134关注 0票数 1

我正在尝试制作一个控制台应用程序来排序和删除重复的图像文件。我有一个文件夹,大约有20000张图片,占用了大约70 of的空间。

我编写了下面的脚本,它似乎运行良好,但问题是,我的PC没有达到一半的可用内存内存(它有16 it )。

代码语言:javascript
运行
复制
static void Main(string[] args)
{
    var uniqueData = new HashSet<string>();
    
    int progress = 0;
    int fileCount = Directory.GetFiles(imageFolderPath).Length;

    foreach (var file in Directory.GetFiles(imageFolderPath))
    {
        string data, year, month;

        using (var image = Image.FromFile(file))
        {

            using (var ms = new MemoryStream())
            {
                image.Save(ms, ImageFormat.Jpeg);
                data = Convert.ToBase64String(ms.ToArray());
            }

            try //try to get image date
            {
                var date = Encoding.UTF8.GetString(image.GetPropertyItem(36867).Value).Split(':');
                year = date[0];
                month = date[1];
            }
            catch
            {
                year = "Unknown";
                month = "Unknown";
            }
        }

        if (!uniqueData.Contains(data))
        {
            uniqueData.Add(data);

            string yearDirectory = Path.Combine(outputFolderPath, year);
                
            if (!Directory.Exists(yearDirectory))
            {
                Directory.CreateDirectory(yearDirectory);
            }

            string monthDirectory = Path.Combine(yearDirectory, (int.TryParse(month, out int i) && i > 0 && i < 14) ? CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i) : month);

            if (!Directory.Exists(monthDirectory))
            {
                Directory.CreateDirectory(monthDirectory);
            }

            File.Move(file, Path.Combine(monthDirectory, Path.GetFileName(file)));
        }
        else
        {
            File.Delete(file);
        }

        progress++;
        Console.WriteLine($"{progress} / {fileCount}");
    }
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2021-04-02 18:55:56

您不需要存储整个文件内容,而是计算散列。另外,将每幅图像转换成JPEG也是不必要的,使用image.RawFormat,它会更快一些。

代码语言:javascript
运行
复制
using (SHA256 sha = SHA256.Create())
using (var ms = new MemoryStream((int)new FileInfo(file).Length))
{
    image.Save(ms, image.RawFormat);
    ms.Position = 0;
    data = Convert.ToBase64String(sha.ComputeHash(ms));
}

第二种选择

代码语言:javascript
运行
复制
if (!uniqueData.Contains(data))
{
    uniqueData.Add(data);
    // ...
}

可以简化为

代码语言:javascript
运行
复制
if (uniqueData.Add(data))
{
    // ...
}

另外,两次获得目录文件也可以是一次。

代码语言:javascript
运行
复制
string[] files = Directory.GetFiles(imageFolderPath);
int fileCount = files.Length;

foreach (var file in files)
{
    // ...
}

最后这个

代码语言:javascript
运行
复制
if (!Directory.Exists(yearDirectory))
{
    Directory.CreateDirectory(yearDirectory);
}

如果Directory.CreateDirectory不存在,则创建目录,否则它什么也不做。您可以删除Exists检查。

代码语言:javascript
运行
复制
Directory.CreateDirectory(yearDirectory);
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/259022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档