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 より約 3 倍高速でした。

キャッシュの影響を除外するために、システムで測定を繰り返しました。

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 ユーティリティでは、SSD をスキャンするのに約 8 秒かかります。

コード:

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 に答える