2013-04-11 79 views
1

我在Windows Mobile上有一些配置文件作为我的解决方案的一部分。我将代码移植到MonoForAndroid和MonoTouch,所以我想尽可能保持我的代码不变。跨平台读取xml文件

当加载这些XML文件,在Windows Mobile正常工作,我在去年的原型,也努力在iOS上,但代码不会对MonForAndroid

工作,我有这些文件

/solution folder 
    /My Documents/ 
     /Business 
      App.Config 
      Settings.Config 

我有这些文件的生成操作设置为Content,我可以看到他们被复制到/bin/Debug/但是当我尝试读取这些文件,我得到以下异常:

System.IO.DirectoryNotFoundException 

我看到here中有类似的问题,但他们建议使用AndroidResources,我不想这样做,有很多放置在需要这些文件的地方,所以我不想在很多地方改变它。

AndrodiResources,是出了问题,如果可能的话,我想尽量避免使用EmbededResources

啊,我读的方式,非常简单xmDoc.Load(filePath)我也试过File.ReadAllText()我确信,该​​文件路径是正确的,和我使用Path.Combine(),以避免与文件路径/斜线 这是我如何构造我的文件路径

var filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Replace(FileURIPrefix, ""), "My Documents", "Business"); 
filePath = Path.Combine(filePath, "App.Config"); 

而且我可以在文件路径是正确的调试器看到任何问题产生的路径 感谢您的帮助提前

+0

如何获取XML文件的路径? – 2013-04-11 07:23:55

回答

0

经过全面搜索后,我无法让MonoDroid在构建操作设置为Content时加载(或包含)我的文件。

我不得不创建一个实体,称为FileHelper它的实现方式不同,在Android上,然后我用FileHelper.ReadAllText(string filename);

我会把我在这里实现,希望这将有利于其他人。

的Windows Mobile和iOS

public class FileHelper 
    { 
     public static string ReadAllText(string filePath) 
     { 
      var path = filePath.GetFullPath(); 
      if (!File.Exists(path)) 
      { 
       Logging.LogHandler.LogError("File " + path + " does not exists"); 
       return string.Empty; 
      } 
      using (var reader = new StreamReader(filePath)) 
      { 
       return reader.ReadToEnd(); 
      } 
     } 
    } 

Android版本

public class FileHelper : BaseFileHelper 
{ 
    public static string ReadAllText(string filePath) 
    { 
     var entryAssemblyPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Replace("file:", ""), "MyExecutableAssemblyName.dll"); 
     // This is because Assembly.GetEntryAssembly() returns null on Android... Booohhh 
     var assembly = Assembly.LoadFrom(entryAssemblyPath); 
     using (var stream = assembly.GetManifestResourceStream(filePath.GetFullPath())) 
     { 
      using (var reader = new StreamReader(stream)) 
      { 
       return reader.ReadToEnd(); 
      } 
     } 
    } 
} 

我有常量的共享代码和路径如下

Constants.cs的一个推广方法

public static Class Constants 
    { 
     private static string _RootPath; 
       private static string _iOSRootPath; 
     private static string _AndroidResourcePath; 

     public static string RootPath 
     { 
      get 
      { 
       if (string.IsNullOrEmpty(_RootPath)) 
       { 
        _RootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Replace(FileURIPrefix, "") + "\\My Documents\\Business"; 
       } 
       return _RootPath; 
      } 
     } 

     public static string iOSRootPath 
     { 
      get 
      { 
          if (!string.IsNullOrEmpty(_iOSRootPath)) 
          { 
         _iOSRootPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Replace(FileURIPrefix, "").Replace("file:", ""), Path.Combine("My_Documents", "Business")); 
        } 
          return _iOSRootPath; 
        } 
     } 

     public static string AndroidResourcePath 
     { 
      get 
      { 
       if (string.IsNullOrEmpty(_AndroidResourcePath)) 
       { 
        _AndroidResourcePath = "Leopard.Delivery.My_Documents.Business."; 
       } 
       return _AndroidResourcePath; 
      } 
     } 
    } 

PathExtentions。CS

public static class PathExtensions 
    { 
     public static string GetFullPath(this string filePath) 
     { 
      if (Platform.IsAndroid) // platform is a class that I have to tell me which platfrom I am at :) 
      { 
       return Constants.AndroidResourcePath + filePath; 
      } 
      if (Platform.IsIOS) 
      { 
       return Path.Combine(Constants.iOSRootPath, filePath); 
      } 
      return Path.Combine(Constants.RootPath, filePath); 
     } 
    } 

设置此功能后,我用我的FileHelper一样简单,如下

string configuratinContents = FileHelper.ReadAllText(configruationPath); 

给谁使用此代码,请记得将生成操作设置为EmbededResources在Android,并Content在iOS和Windows Mobile上。