繁体   English   中英

从Xamarin.Android项目中的文件读取

[英]Reading from a file in Xamarin.Android project

我正在尝试从Xamarin Android中的MainActivity类访问.pbf文件。 我尝试将文件添加到新的Maps文件夹,也尝试将其添加到Assets and Resources文件夹。

我尝试用不同的构建操作设置它们。 但是,始终会生成此错误...“ System.IO.FileNotFoundException:找不到文件”

using (var inputStream = 
   new FileInfo(@"Resources\ireland.osm.pbf").OpenRead())
{
...
}

应该如何将文件添加到项目中并使用FileInfo访问?

首先,您可能想做的是使用Assets并遵循本教程

在应用程序中包含文件的工作原理与直接在文件系统上访问文件一样。 现在您将无法从资产中获取FileInfo ,但是您将能够读取它们。

首先将ireland.osm.pbf文件放在Assets目录中。 接下来,您必须将Build Action设置为AndroidAsset如果选择Add Existing Item ,通常会为您完成)。 这会将文件构建(打包)为Android Package的一部分。

接下来的资产通过AssetManager加载(访问)。 幸运的是,可以通过this.Assets在活动上下文中使用。

读取资产非常简单。

using (StreamReader sr = new StreamReader (Assets.Open ("ireland.osm.pbf")))
{
    //do as you wish with the stream reader.
}

编辑:

从评论。

但我需要FileInfo来实现PBFOsmStreamSource(),如此处所示链接

我快速浏览了PBFOsmStreamSource()的源代码,并使用了构造函数:

/// <summary>
/// Creates a new source of PBF formated OSM data.
/// </summary>
/// <param name="stream"></param>
public PBFOsmStreamSource(Stream stream)
{
    _stream = stream;
}

现在,流读取器不是 Stream我们需要将其转换为Stream但是具有属性BaseStream 现在,鉴于我没有测试环境,您应该可以致电。

using (StreamReader sr = new StreamReader(Assets.Open("ireland.osm.pbf")))
{
    //do as you wish with the stream reader.
    var pbfStreamSource = new PBFOsmStreamSource(sr.BaseStream);

}

编辑2

StreamReader.BaseStream()不支持Seek()方法。 显示有关PBFOsmStreamSource

private void Initialize()
{
    _stream.Seek(0, SeekOrigin.Begin);

    this.InitializePBFReader();
}

这就是为什么出现System.NotSupporte‌​dException异常的原因。 因此,您将需要构造一个支持Seek()方法的流。 幸运的是, MemoryStream能够更改位置并支持Seek()方法。

同样,我没有测试环境。

using (StreamReader sr = new StreamReader(Assets.Open("ireland.osm.pbf")))
{
    using (var ms = new MemoryStream())
    {
        sr.BaseStream.CopyTo(ms);
        var pbfStreamSource = new PBFOsmStreamSource(ms);
    }
}

最终编辑

经过更多的审查并查看了他们的样本之后,我编写了一个示例控制台应用程序,该应用程序使用StreamReader的方式与您在移动设备上的使用方式相同。 现在,我对此进行了一些微调,以便我们可以快速处理StreamReader ,因为这些文件会占用大量内存,并且无需一次打开两个流。

using OsmSharp.Geo;
using OsmSharp.Osm.PBF.Streams;
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace Sample.GeometryStream
{
    class Program
    {
        static void Main(string[] args)
        {
            Test();
            Console.ReadLine();

        }
        static async Task Test()
        {

            await ToFile("http://files.itinero.tech/data/OSM/planet/europe/luxembourg-latest.osm.pbf", "test.pbf");

            var sr = new StreamReader("test.pbf");
            using (var ms = new MemoryStream())
            {
                try
                {
                    sr.BaseStream.CopyTo(ms);
                }
                catch
                {
                    //TODO: Handle exceptions
                }
                finally
                {
                    sr.Close();
                    sr.Dispose();
                }
                var pbfStreamSource = new PBFOsmStreamSource(ms);
            }
        }

        public static async Task ToFile(string url, string filename)
        {
            if (!File.Exists(filename))
            {
                var client = new HttpClient();
                using (var stream = await client.GetStreamAsync(url))
                using (var outputStream = File.OpenWrite(filename))
                {
                    stream.CopyTo(outputStream);
                }
            }
        }

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM