我需要提供一个包含本地存储的 zip 文件内容的 WebView。
我使用NavigateToLocalStreamUri()方法并以与 Windows 库链接 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(异常(exception))声明“无效转换操作”。
还要注意,在调试过程中,在调用 AsInputStream() 时,流的类型并不像人们预期的那样:IInputStream 类型,而是 System.IO.NetFxToWinRtStreamAdapter.InputStream 类型
进一步扩展对象,将非公共(public)成员“ManagedStream”视为 System.IO.Compression.DeflateStream 类型
我假设有一些方法可以使用 DataReader 将流转换为内存流,然后转换回 IInputstream,但这似乎违反直觉,因为提供的 AsInpuSream() 方法应该按预期工作。
最佳答案
据我所知,似乎没有办法绕过 IInputStream() 返回类型为:System.IO.NetFxToWinRtStreamAdapter 的流。输入流
我编写了以下方法来手动将字节复制到新流中,仅使用 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
}
}
关于c# - WinRT/Metro/WSA 向 WebView 提供来自 ZipArchive 的流的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22251075/