【问题标题】:Cross-Platform reading of xml files跨平台读取xml文件
【发布时间】:2013-04-11 07:20:30
【问题描述】:

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

加载这些 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");

我可以在调试器中看到 filePath 是正确的 提前感谢您的帮助

【问题讨论】:

  • 如何获取 XML 文件的路径?

标签: c# android ios visual-studio xamarin.android


【解决方案1】:

四处搜索后,当 MonoDroid 的构建操作设置为 Content 时,我无法让 MonoDroid 加载(或包含)我的文件。

我必须创建一个名为 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();
            }
        }
   }

安卓版本

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();
            }
        }
    }
}

我有一个常量共享代码和一个路径扩展方法,如下所示

常量.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); 

对于使用此代码的任何人,请记住在 Android 上将构建操作设置为 EmbededResources,在 iOS 和 Windows Mobile 上设置为 Content

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    相关资源
    最近更新 更多