首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# -检索扩展属性的Shell32对象的最佳替代方案

C# -检索扩展属性的Shell32对象的最佳替代方案
EN

Stack Overflow用户
提问于 2022-06-06 14:49:15
回答 1查看 76关注 0票数 0

我真的在如何设计我的程序上陷入困境,简单地说,它需要在给定路径中创建一个文件列表,然后按日期对它们进行排序,创建相应的子目录。问题的产生是因为这些文件是由NAS中的电话上传的,它们的创建日期在上传到这个驱动器时会被修改。由于我们讨论的是照片、视频或音频,所以我尝试使用元数据检索存储在基于this answer的元数据中的一些常见日期的最佳方法如下:

代码语言:javascript
复制
internal static class FileInSorting
{
    private static List<string> arrHeaders;
    private static List<int> date = new List<int>() { 197, 3, 4, 5, 12, 198, 287, 208 };
    private static List<FileToSort> fileToSort = new List<FileToSort>();

    public static List<FileToSort>  GetFilesToSort(string path)
    {
        Folder objFolder;
        LoadHeader(path, out arrHeaders, out objFolder);

         //I search for each file inside his extended property for the true creation date
         //If none is found I default to what FileInfo thinks is right
        foreach (Shell32.FolderItem2 item in objFolder.Items())
        {
            List<DateTime> tmp = new List<DateTime>();
            DateTime SelectedDate;
            foreach (int h in date)
            {
                string l = objFolder.GetDetailsOf(item, h);
                if (!string.IsNullOrEmpty(l))
                {
                    string asAscii = Encoding.ASCII.GetString(
                        Encoding.Convert(
                            Encoding.UTF8,
                            Encoding.GetEncoding(
                                Encoding.ASCII.EncodingName,
                                new EncoderReplacementFallback(string.Empty),
                                new DecoderExceptionFallback()),
                            Encoding.UTF8.GetBytes(l)
                            )
                        );

                    tmp.Add(DateTime.Parse(asAscii.Substring(0, 11)));
                }
            }
            if (tmp.Count == 0)
                SelectedDate = File.GetCreationTime(item.Path);
            else
                SelectedDate = tmp.Min();
            fileToSort.Add(new FileToSort(item.Name, item.Path, SelectedDate));


        }
        return fileToSort;
    }
    public static void LoadHeader(string path, out List<string> arrHeaders, out Folder objFolder)
    {
        arrHeaders = new List<string>();
        Shell32.Shell shell = new Shell32.Shell();
        objFolder = shell.NameSpace(path);

        for (int i = 0; i < short.MaxValue; i++)
        {
            string header = objFolder.GetDetailsOf(null, i);
            if (!String.IsNullOrEmpty(header))
                arrHeaders.Add(header);
        }
    }
}

我做这个类只是为了便于排序,但它可能是完全多余的。

代码语言:javascript
复制
   public class FileToSort
    {
        public string nome { get; set; }
        public string path { get; set; }
        public DateTime sortDate { get; set; }
        public FileToSort(string nome,string path,DateTime data)
        {
            this.nome = nome;
            this.path = path;
            this.sortDate = data;
        }
    }

使用这个COM对象的问题是速度慢,不太容易处理(也许我只是无法处理),正如我在另一个问题上所发现的,它不是线程安全的,在第一次排序之后阻止了对多个文件夹进行并行操作的选项。例如,我首先对树结构中的所有文件进行排序--“年/月/满日期”,但之后我必须为每个“完整日期”文件夹重新创建COM对象,并按类型对这些文件进行排序。我知道,在第一次日期排序之后,我可以开始对每个新创建的文件夹使用Directory.EnumerateFile(),但是我想看看是否有更好的方法来“设计”代码,这样就可以在不为日期排序和类型排序编写两个单独的方法的情况下重用它,那么有什么方法可以完全避免使用Com对象吗?

快速编辑我忘了另一个为什么我要寻找另一个解决方案:

这是一个WPF应用程序,我很想使用绑定到单个集合(也许是ListView集合)的一个FileInfo集合。

EN

回答 1

Stack Overflow用户

发布于 2022-06-06 15:16:57

出现了问题,因为文件在网络中,它们的创建日期在上传时会被修改

这是你的选择,也是你的问题。如果您不想在上传时更改文件日期,请不要更改它们。例如,Windows Explorer默认不会更改它们,您将获得与源相同的创建日期。您自己的代码可以完全访问要使用的日期。

我创建这个类只是为了在排序过程中容易使用,但是它可能是完全多余的。

你应该去查一下record。以及正确的.Net命名约定(公共属性应该大写)。

--它不是线程安全的,在第一次排序之后,阻止了对多个文件夹进行并行操作的选项

你这是在胡思乱想。它可能不是线程安全的,但是没有什么可以阻止您创建多个要查询的对象,每个线程一个。查找线程-局部变量和/或静力学。

,但是我必须为每个“完整日期”文件夹重新创建COM对象,并按类型对这些文件夹进行排序。

这一行有点难理解,但是如果您说您“需要”再次请求整个文件系统,只为了排序项,那么您就大错特错了。排序是一个视图操作,模型并不关心它,您在这里编写的是模型。对视图的排序可以任意处理,您已经将数据存储在内存中,按您的意愿进行排序。

我不想把你的代码看得太深,但天哪,这是什么?

代码语言:javascript
复制
                string asAscii = Encoding.ASCII.GetString(
                    Encoding.Convert(
                        Encoding.UTF8,
                        Encoding.GetEncoding(
                            Encoding.ASCII.EncodingName,
                            new EncoderReplacementFallback(string.Empty),
                            new DecoderExceptionFallback()),
                        Encoding.UTF8.GetBytes(l)
                        )
                    );

如果我不得不给你打分的话,我数到0的时候你就会被解雇.用原来的绳子,你在做什么,伙计?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72519436

复制
相关文章

相似问题

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