【问题标题】:C# Get File properties without using System.IO.FileInfoC# 在不使用 System.IO.FileInfo 的情况下获取文件属性
【发布时间】:2013-01-04 16:01:11
【问题描述】:

是否可以在不使用System.IO.FileInfo 的情况下从给定文件中提取“某些”属性?

我的意思是,我喜欢在我只有几个文件要处理的情况下使用FileInfo,但是如果,例如,我想从 50 万个文件中获取文件名列表,并且我决定使用FileInfo... 这需要永远!

我怀疑FileInfo 将一堆关于该文件的其他内容加载到内存中(对吗?)。如果是这样,我觉得应该有一种更快的方法来获取名称或文件扩展名。

另一方面,我可以只使用Directory.GetFiles(myPath),但这会给我一个包含每个文件的完整路径的数组,而我只需要名称每个文件! (我想我可以解析路径字符串以从中提取名称......这会比使用FileInfo 更快吗?)

如果我想更快地完成此操作(获取文件名或获取文件扩展名),还有哪些其他选择?

非常感谢!!

【问题讨论】:

    标签: c# filenames fileinfo getfiles system.io.fileinfo


    【解决方案1】:

    您正在寻找Path 类中的方法。

    具体来说,Path.GetFileName() 和 Path.GetExtension()。

    【讨论】:

    • 天哪!感谢闪电般的快速回答!我会试一试的。
    【解决方案2】:

    受您的问题启发,我比较了 FileInfo 和 FileSystemObject。我测量了遍历 SSD 驱动器所需的时间。

    实质上,FileInfo 的速度大约是 FileSystemObject 的三倍。

    我在我的系统上重复了测量以排除缓存影响:

    test FileInfo Files: 489557 Directories: 66023
    FileInfo traversal needed 12,07s
    
    test FileSystemObject. Files: 489557 Directories: 66023 
    FileInfo traversal needed 38,59s
    

    尝试使用 Windows API 可能是值得的。但是由于 Marshalling,调用和参数传递必须支付性能费。

    一个自制的 C 实用程序需要大约 8 秒来扫描 SSD。

    代码:

    using System;
    using System.Linq;
    
    using Scripting;
    using System.Diagnostics;
    using System.IO;
    
    namespace akTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Stopwatch watch = new Stopwatch();
    
                watch.Start();
                testFileInfo(@"c:\");
                watch.Stop();
                o("FileInfo traversal needed " + (watch.ElapsedMilliseconds/1000.0).ToString("#.##") + "s");
    
                watch.Start();
                testFSO(@"c:\");
                watch.Stop();
                o("FileInfo traversal needed " + (watch.ElapsedMilliseconds / 1000.0).ToString("#.##") + "s");
    
                o("");
                o("Ciao!");
            }
    
            static void o(string s)
            {
                Console.WriteLine(s);
            }
    
            static void testFileInfo(string dir)
            {
                DirectoryInfo di = new DirectoryInfo(dir);
                long fileCount = 0;
                long dirCount = 0;
                long calls = 0;
    
                o("Testing FileInfo");
    
                WalkDirectoryTree(di, ref fileCount, ref dirCount, ref calls);
    
                o("testFileInfo completed. Files: " + fileCount + " Directories: " + dirCount + " Calls: " + calls);
            }
    
            static void testFSO(string dir)
            {
                FileSystemObject fso = new FileSystemObject();
                Folder folder = fso.GetFolder(dir);
    
                long fileCount = 0;
                long dirCount = 0;
                long calls = 0;
    
                o("Testing FSO");
    
                WalkDirectoryTree(folder, ref fileCount, ref dirCount, ref calls);
    
                o("testFSO completed. Files: " + fileCount + " Directories: " + dirCount + " Calls: " + calls);
            }
    
            static void WalkDirectoryTree(DirectoryInfo root, ref long fileCount, ref long dirCount, ref long calls)
            {
                FileInfo[] files = null;
                DirectoryInfo[] subDirs = null;
    
                if (++calls % 10000 == 0)
                    o("" + calls);
    
                try
                {
                    files = root.GetFiles("*.*");
    
                    if (files != null)
                    {
                        fileCount += files.Count();
                        subDirs = root.GetDirectories();
                        dirCount += subDirs.Count();
    
                        foreach (DirectoryInfo dirInfo in subDirs)
                        {
                            WalkDirectoryTree(dirInfo, ref fileCount, ref dirCount, ref calls);
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
    
    
            static void WalkDirectoryTree(Folder root, ref long fileCount, ref long dirCount, ref long calls)
            {
                Files files = null;
                Folders subDirs = null;
    
                if (++calls % 10000 == 0)
                    o("" + calls);
    
                try
                {
                    files = root.Files;
    
                    if (files != null)
                    {
                        fileCount += files.Count;
                        subDirs = root.SubFolders;
                        dirCount += subDirs.Count;
    
                        foreach (Folder fd in subDirs)
                        {
                            WalkDirectoryTree(fd, ref fileCount, ref dirCount, ref calls);
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
        }
    }
    

    【讨论】:

    • 这是非常有趣的信息。谢谢!我会潜入。
    【解决方案3】:

    如果您只对文件名感兴趣,可以使用Path.GetFilename 获取文件名。

    【讨论】:

    • 谢谢!当我们“说话”时,我正在检查这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    • 2021-03-15
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    相关资源
    最近更新 更多