我需要提供一个包含本地存储的zip文件内容的WebView。
我使用NavigateToLocalStreamUri()方法并提供我自己的扩展UriResolver,方法与Windows库链接NavigateToLocalStreamUri()上的示例相同。
但是,由于“NTLSUri”方法无法识别流的类型并尝试强制转换,因此调试失败的情况相当惊人。有谁知道如何正确地从压缩存档元素提供流到WebView?
以下是详细信息:
这是我自己定制的GetContent()方法,用于为归档元素提供流而不是正常流。
private async Task<IInputStream> GetNormalZipEntryStream(String archivePath)
{
StorageFolder current = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("bookTest");
bookSourceFile = await current.GetItemAsync("testBook.zip") as StorageFile;
if (archivePath.ElementAt(0) == '/') archivePath = archivePath.Remove(0, 1);
Stream bookZipStream = await bookSourceFile.OpenStreamForReadAsync();
ZipArchive bookArchive = new ZipArchive(bookZipStream, ZipArchiveMode.Read);
ZipArchiveEntry bookContentFile = bookArchive.GetEntry(archivePath);
if (bookContentFile == null)
throw new Exception("Invalid archive entry");
else
{
try
{
IInputStream stream = bookContentFile.Open().AsInputStream();
return stream;
}
catch (Exception ex)
{
var streamConvErr = ex.Message;
}
}
return null;
}
现在,一切正常,我能够成功获得存档元素的流。我还确认ArchiveElement.Open()方法确实返回了一个包含“未压缩”内容的流。
问题是 - 在幕后 - NAvigateToStreamUri()方法无法接受bookContentFile.Open()返回的IInput流.AsInputStream()。
它会在以下代码部分导致调试器中断:
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
此时e(例外)声明“无效的演员操作”。
另请注意,在调试期间,在调用AsInputStream()时,stream的类型不像预期的那样:类型为IInputStream,而是类型为System.IO.NetFxToWinRtStreamAdapter.InputStream
扩展对象进一步将非公共成员“ManagedStream”视为System.IO.Compression.DeflateStream类型
我假设有一些方法可以使用DataReader将流转换为内存流,然后转换回IInputstream,但这似乎是违反直觉的,因为提供的AsInpuSream()方法应该按预期工作。
答案 0 :(得分:1)
似乎没有办法...据我所知......绕过 IInputStream()返回Type: System.IO.NetFxToWinRtStreamAdapter的流。的InputStream
我编写了以下方法,仅使用Windows.Storage.Stream类型手动将字节复制到新流中。 WebView没有任何抱怨,一切正常
private async Task<IInputStream> GetInputStreamFromIOStream(System.IO.Stream stream, long fileSize)
{
try
{
BinaryReader binReader = new BinaryReader(stream);
byte[] byteArr = binReader.ReadBytes((int)fileSize);
var iMS = new InMemoryRandomAccessStream();
var imsOutputStream = iMS.GetOutputStreamAt(0);
DataWriter dataWriter = new DataWriter(imsOutputStream);
dataWriter.WriteBytes(byteArr);
await dataWriter.StoreAsync();
await imsOutputStream.FlushAsync();
return iMS.GetInputStreamAt(0);
}
catch(Exception ex)
{
//Error Handling here
return null;
}
}
以下列方式为感兴趣的人实施:
sourceFile = await current.GetItemAsync("zipfileHere.zip") as StorageFile;
Stream zipStream = await sourceFile.OpenStreamForReadAsync();
ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Read);
ZipArchiveEntry contentFile = archive.GetEntry(archivePathVar);
if (contentFile == null)
throw new Exception("Invalid archive entry");
else
{
try
{
var zipASize = contentFile.Length;
IInputStream stream = await GetInputStreamFromIOStream(contentFile.Open(), zipASize);
return stream;
}
catch (Exception ex)
{
//Some error handling here
}
}
答案 1 :(得分:0)
试试这个:
try
{
IInputStream stream = bookContentFile.Open().AsRandomAccessStream().GetInputStreamAt(0);
return stream;
}
catch (Exception ex)
{
var streamConvErr = ex.Message;
}
基本上,这会首先将流转换为Windows运行时等效项,然后使用内置方法获取IInputStream
版本。