我已经实现了类似于 this 的东西 唯一真正的区别是
string filename = context.Request.RawUrl.Replace("/", "\\").Remove(0,1);
string path = Uri.UnescapeDataString(Path.Combine(_baseFolder, filename));
这样我就可以遍历子目录了。这对网页和其他文本文件类型非常有用,但在尝试提供媒体内容时出现异常
HttpListenerException: The I/O operation has been aborted because of either a thread exit or an application request
紧随其后
InvalidOperationException: Cannot close stream until all bytes are written.
在using语句中。
关于如何处理这个或停止这些异常有什么建议吗?
谢谢
最佳答案
我应该提到我在我的浏览器中使用谷歌浏览器(谷歌浏览器似乎不关心 MIME 类型,当它看到音频时它会尝试像在 HTML5 播放器中一样使用它),但这是如果您尝试在页面中托管媒体内容,也适用。
无论如何,我正在用 fiddler 检查我的 header ,并注意到 Chrome 向服务器传递了 3 个请求。我开始尝试使用其他浏览器并注意到它们并没有这样做,但是根据浏览器和我硬编码为 MIME 类型的内容,我要么得到一页疯狂的文本,要么得到一个文件的下载。
经过进一步检查,我注意到 chrome 会首先请求该文件。然后使用几个不同的 header 再次请求文件,最显着的是范围 header 。第一个 byte=0- 然后下一个具有不同的大小,具体取决于文件的大小(可以发出 3 个以上的请求,具体取决于文件的大小)。
所以问题来了。 Chrome 将首先询问该文件。一旦看到类型,它会发送另一个请求,在我看来,它正在寻找文件有多大(字节= 0-),然后另一个请求要求文件的后半部分或类似的东西,以允许在使用时体验一种流式传输HTML5。我快速编写了一些代码来处理 MIME 类型,并将一个 HTML5 页面与音频组件放在一起,发现其他浏览器也这样做(IE 除外)
所以这是一个快速的解决方案,我不再遇到这些错误
string range = context.Request.Headers["Range"];
int rangeBegin = 0;
int rangeEnd = msg.Length;
if (range != null)
{
string[] byteRange = range.Replace("bytes=", "").Split('-');
Int32.TryParse(byteRange[0], out rangeBegin);
if (byteRange.Length > 1 && !string.IsNullOrEmpty(byteRange[1]))
{
Int32.TryParse(byteRange[1], out rangeEnd);
}
}
context.Response.ContentLength64 = rangeEnd - rangeBegin;
using (Stream s = context.Response.OutputStream)
{
s.Write(msg, rangeBegin, rangeEnd - rangeBegin);
}
关于C#:提供内容的 HttpListener 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6549226/