C#在不使用System.IO.FileInfo的情况下获取文件属性

时间:2013-01-04 16:01:12

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

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

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

我怀疑FileInfo将一堆关于该文件的其他东西加载到内存中(这是正确的吗?)。如果是这样,我觉得应该有一种更快的方法,比如,只需抓取名称或文件扩展名。

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

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

非常感谢!!

3 个答案:

答案 0 :(得分: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可能是值得的。但是由于编组,调用和参数传递必须支付性能费。

家庭成长的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)
            {
            }
        }
    }
}

答案 1 :(得分:2)

您正在寻找Path课程中的方法。

具体而言,Path.GetFileName()Path.GetExtension()

答案 2 :(得分:1)

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