我需要提供来自本地存储的zip文件的内容的WebView。
我使用navigateTolocalStreamuri()方法,并以与Windows Library链接到NavigateTolocalStreamuri()的示例相同的方式提供了自己的扩展Uriresolver()。
但是,由于" 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()。asinputstream()返回的iinput流。
在以下代码部分中导致调试器中断:
#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()的点,流的类型不像人们期望的那样:IinputStream类型,而是类型system.io.netfxtowinrtstreamadapter.inputstream.inputstream
进一步扩展对象将非公共成员"托管stream"为type system.oio.compression.deflateStream
我假设有使用DataReader将流将流转换为存储流然后转换回IinputStream的方法,但这似乎是违反直觉的,因为所提供的Asinpusream()方法应按预期工作。
似乎没有办法...据我所知...绕 iinputstream()返回类型流: 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
}
}
尝试以下:
try
{
IInputStream stream = bookContentFile.Open().AsRandomAccessStream().GetInputStreamAt(0);
return stream;
}
catch (Exception ex)
{
var streamConvErr = ex.Message;
}
基本上,这将流转换为Windows运行时等效物,然后使用内置方法获取IInputStream
版本。