我正在尝试从Xamarin Android中的MainActivity类访问.pbf文件。我尝试将文件添加到新的Maps文件夹中,我也尝试将其添加到Assets and Resources文件夹中。
我尝试使用不同的构建操作设置它们。但是总是生成此错误...“System.IO.FileNotFoundException:找不到文件”
using (var inputStream =
new FileInfo(@"Resources\ireland.osm.pbf").OpenRead())
{
...
}
如何将文件添加到项目中并使用FileInfo进行访问?
答案 0 :(得分:2)
首先,您可能要做的是使用资产并按照Tutorial
进行操作包含文件,因为您的应用程序无法像在文件系统上直接访问它们那样工作。现在,您无法从资产中获取FileInfo
,但您将能够阅读它们。
首先将ireland.osm.pbf
文件放在Assets
目录中。接下来,您必须(并且通常在您选择添加现有项目时为您执行此操作)将构建操作设置为AndroidAsset
。这将构建(打包)文件作为Android包的一部分。
通过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;
}
现在,流阅读器是 NOT 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.NotSupportedException
例外的原因。因此,您需要构建支持Seek()
方法的流。 Fortunatly 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);
}
}
}
}
}