1

是否可以从给定文件中提取“某些”属性而不使用System.IO.FileInfo

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

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

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

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

非常感谢你!!

4

3 回答 3

3

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

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

于 2013-01-04T16:02:20.317 回答
3

受您的问题启发,我比较了 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)
            {
            }
        }
    }
}
于 2013-01-04T17:41:57.887 回答
1

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

于 2013-01-04T16:03:13.237 回答