Winrt/Metro/WSA问题可从Ziparchive提供WebView



我需要提供来自本地存储的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版本。

最新更新