在Mono - Linux上使用FileInfo和DirectoryInfo类

Omk*_*kar 2 .net c# linux mono

我这里有两个小问题.

  1. 我正在开发一个我们想要在Linux上执行的.net应用程序.我明显的选择是使用Mono运行它.此应用程序使用广泛的文件和目录枚举并收集文件和目录信息.当我浏览Mono Documentation时,我发现Mono分别设计了UnixDirectoryInfo,UnixFileInfo类.我的查询是,这是否意味着他们不支持在BCL(System.IO名称空间)中的FileInfo和DirectoryInfo.

  2. 我知道.NET中的传统文件和目录枚举很慢,我已经阅读了许多文章,人们建议在Windows上使用FindFirst(...)FindNext(...)进行PInvoke调用.我完全清楚这在Linux上不起作用.有没有人在Mono Linux上专门在这个领域工作以测试File/Dir枚举性能.

谢谢,Omky

use*_*830 5

从技术上讲,它在Linux机器上应该更快,因为文件系统枚举通常比Windows快.

但是我们想要根据自定义Mono.Posix评估Mono BCL,我检查了两个程序集的底层实现,虽然两者都会在最后调用系统函数,但路由不同,因为前者使用Mono运行时抽象,但后者使用直接p/invoke ,所以我写了一个简单的代码来评估Directory和File枚举的性能差异,这里是:

    public static void Main (string[] args)
    {
        Assess ("/opt",5, false);
        Console.WriteLine ("**********************");
        Assess ("/opt",5, true);
    }

    public static void Assess (string root,int iteration, bool net=true)
    {
        var watch = new Stopwatch ();
        var fCount = 0;
        var dCount = 0;

        watch.Start ();
        for (var i=0; i<iteration; i++) {
            if (net) {
                Console.WriteLine ("assessing .Net Bcl");
                var dirInfo = new System.IO.DirectoryInfo (root);
                AssessNet (dirInfo, ref fCount, ref dCount);
            } else {
                Console.WriteLine ("assessing Mono Posix");
                var unixDirInfo = new Mono.Unix.UnixDirectoryInfo (root);
                AssessMono (unixDirInfo, ref fCount, ref dCount);
            }
        }
        watch.Stop ();
        Console.WriteLine ("crawl time: {0} ms", watch.ElapsedMilliseconds);
        Console.WriteLine ("files count: {0}, directory count: {1}", fCount, dCount);
    }

    public static void AssessNet (System.IO.DirectoryInfo root, ref int fCount, ref int dCount)
    {
        var files = root.GetFiles ();
        var dirs = root.GetDirectories ();

        foreach (var f in files) {
            fCount++;
        }

        foreach (var d in dirs) {
            dCount++;
            AssessNet (d, ref fCount, ref dCount);
        }
    }

    public static void AssessMono (Mono.Unix.UnixDirectoryInfo root,ref int fCount,ref int dCount)
    {
        var entries = root.GetFileSystemEntries ();

        foreach (var e in entries) {
            if (e.IsDirectory) {
                dCount++;
                AssessMono (e as Mono.Unix.UnixDirectoryInfo,ref fCount,ref dCount);
            } else {
                fCount++;`enter code here`
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在Ubuntu 14.04.1 64位上使用Mono 3.2.8进行了测试

结果如下:

评估Mono Posix

抓取时间:469毫秒,文件数:16020,目录数:2965


评估.Net Bcl

爬网时间:705毫秒,文件数:16020,目录数:2965

基于我的实验,存在性能差异,因此根据您的要求,并考虑两个API之间的细微差别,编写一个瘦包装器以在两个操作系统上实现最佳结果可能不是一个坏主意(我们可以使用直接在Windows上调用Win32,因为.Net中的文件和目录IO的默认实现也很慢).