2014-09-05 70 views
2

我在这里有两个小问题。Mono上的FileInfo和DirectoryInfo类的用法 - Linux

  1. 我的工作,我们要执行在Linux上 太.NET应用程序之一。我明显的选择是使用Mono来运行它。这 应用程序正在使用广泛的文件和目录枚举和 收集文件和目录信息。当我通过Mono Documentation时,发现Mono分别设计了UnixDirectoryInfo, UnixFileInfo类。我的查询是,这是否表示 他们不支持BCL(System.IO名称空间)中的 FileInfo和DirectoryInfo。

  2. 我知道,在.NET 传统的文件和目录的枚举是缓慢的,我已经经历了很多文章,人们推荐使用 用的PInvoke在Windows上使用FindFirst(...)FindNext中(...)调用了。我完全意识到这一点在Linux上不起作用。有没有人专门在Mono Linux上工作 来测试File/Dir 枚举的性能。

感谢, Omky

+0

看看这里;)https://github.com/mosa/Mono-Class-Libraries/blob/master/mcs/class/corlib/System.IO/FileInfo.cs – 2014-09-09 12:55:50

+0

他们支持FileInfo和DirectoryInfo at至少在3.6(我相信它已经在那里很长一段时间了)。它可以在内部重定向到UnixFile/DirInfo。我不确定。至于性能,我认为它在Linux/Unix上运行速度非常快,因为它们的文件系统本质上更快(由于我没有数据支持它,因此有争论,而且没有科学准确性),但要查明,编写一个测试用例并在你的发行版中运行它来测试你的用例。我没有任何性能数据,但是当我使用它时,它并不明显很慢。如果有的话,它看起来更快。 – kha 2014-09-12 08:09:41

回答

5

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

但我们想要评估Mono BCL对Mono.Posix的自定义,我检查了两个程序集的底层实现,并且尽管两者都会在最后调用系统函数,但由于前者使用Mono运行时抽象,但后者使用直接的p/Invoke,所以我写了一个简单的代码来评估目录和文件枚举性能差异,那就是:

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` 
      } 
     } 
    } 
} 

我在Ubuntu 14.04.1使用Mono 3.2.8测试的64位

结果如下:

评估单的Posix

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


评估.NET基础类库

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

根据我的实验有一个执行因此,根据您的要求,并考虑到两个API之间的细微差异,在操作系统 (我们可以在Windows上使用直接Win32调用作为最佳结果编写薄包装器可能不是一个坏主意.Net中File和Directory IO的默认实现也很慢)。

+0

您的回答帮助我决定实施策略很多....非常感谢!!!!! – Omkar 2014-09-23 08:27:35

2

我发现,单声道设计UnixDirectoryInfo,UnixFileInfo类 分开。我的查询是,这是否意味着它们不支持它们在BCL(System.IO名称 空间)中的 FileInfo和DirectoryInfo。

是支持System.IO.FileInfo & System.IO.DirectoryInfoMono.Unix.FileInfo & Mono.Unix.DirectoryInfo一起。因此,为了编写便携式代码,我们应该使用System.IO工具。下面的示例代码已被写入其采用System.IO

VERSIONINFO

MonoDevelop 3.1.0 
Installation UUID: e5e69249-f5d5-40a6-9424-2ecbdf6c71c7 
Runtime: 
    Mono 2.10.8.1 (Debian 2.10.8.1-1ubuntu2.2) (64-bit) 
    GTK 2.24.10 
    GTK# (2.12.0.0) 
Build information: 
    Git revision: unknown 
    Build date: 2012-08-15 10:45:07+0000 
Operating System: 
    Linux 
    Linux mantosh-Inspiron-3521 3.2.0-67-generiC#101-Ubuntu S 
    MP Tue Jul 15 17:46:11 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux 

SampleProgram

using System; 
using System.IO; 

namespace Test 
{ 
    class DirInformation 
    { 
     static public void DoSomething() 
     { 
      string name = null; 
      name = "/home/mantosh/"; 
      DirectoryInfo info = new DirectoryInfo (name); 
      bool dirExists = info.Exists; 
      Console.WriteLine(dirExists); 
     } 

     public static void Main (string[] args) 
     { 
      DoSomething(); 
     } 
    } 
} 

我深知,这将不会工作在Linux上。有没有人在Mono Linux上专门在这方面工作过 来测试File/Dir枚举 的性能。

我认为不是猜测,我们应该编写示例应用程序并验证性能。我还没有对MONO进行任何性能分析,但通常任何框架/库代码都会比直接系统调用慢一点。但与 框架/库,我们得到更好的错误处理,当然更便携的代码。

我的建议是,如果你的意图是编写一个可移植的应用程序,你应该坚持框架(在这种情况下是单声道)。