.net IHTTPHandler 流式 SQL 二进制数据
我正在尝试为流文件实现 ihttphandeler。文件可能是微小的缩略图或巨大的电影
存储在 sql server 中的二进制文件
我在网上看了很多代码,但有些东西没有意义
流不是应该逐段读取数据并将其移动到线上吗?
大多数代码似乎首先将整个字段从 mssql 读取到内存,然后使用流式传输进行输出写入
实际上从磁盘直接逐字节流式传输到 http(或缓冲块)不是更有效吗
到目前为止,这是我的代码,但无法弄清楚 sqlreader 模式和流对象以及写入系统
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.BufferOutput = False
Dim FileField=safeparam(context.Request.QueryString("FileField"))
Dim FileTable=safeparam(context.Request.QueryString("FileTable"))
Dim KeyField=safeparam(context.Request.QueryString("KeyField"))
Dim FileKey=safeparam(context.Request.QueryString("FileKey"))
Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("Main").ConnectionString)
Using command As New SqlCommand("SELECT " & FileField & "Bytes," & FileField & "Type FROM " & FileTable & " WHERE " & KeyField & "=" & FileKey, connection)
command.CommandType = Data.CommandType.Text
最终使用的 正确组合 结束使用 end sub
请注意,此 sql 命令还会在查询的第二个字段中返回文件扩展名(pdf、jpg、doc...),
非常感谢大家
编辑:
我设法找到了一些更多代码,现在页面间歇性地显示。有时它会带来 pdf 文件,有时则不会
我无法理解这里的模式
我认为主要问题是当请求来自不同的页面并且我单击“在新选项卡中显示”时,它就永远不起作用。当我“在新窗口中显示”时,它大部分有效,但并非总是有效。
顺便提一句。代码始终运行。永远不会中断或错误或类似的事情。对于每个请求,它从头到尾都像个好孩子一样运行
有时 IE 会在很长一段时间后给我一条消息(从新选项卡)“Adobe/Acrobat reader 有问题。请退出 Adobe Acrobat/Reader 并重试。”
这是怎么回事?
这是我当前的代码,
Shared Sub ProccessMedia(ByVal context As HttpContext)
If CurPerson Is Nothing OrElse Not CurPerson.PersonExts.FirstOrDefault.LetAllFiles Then Exit Sub
context.Response.BufferOutput = False
Dim FileField = SafeParam(context.Request.QueryString("FileField"))
Dim FileTable = SafeParam(context.Request.QueryString("FileTable"))
Dim KeyField = SafeParam(context.Request.QueryString("KeyField"))
Dim FileKey = SafeParam(context.Request.QueryString("FileKey"))
Dim oSqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("Main").ConnectionString)
Dim oSqlCommand = New SqlCommand("SELECT " & FileField & "Type," & FileField & "Bytes FROM " & FileTable & " WHERE " & KeyField & "=" & FileKey, oSqlConnection)
oSqlConnection.Open()
Dim oSqlDataReader = oSqlCommand.ExecuteReader(CommandBehavior.SequentialAccess)
If oSqlDataReader.Read() Then
context.Response.ContentType = GetMIMEType(oSqlDataReader.GetString(0))
Dim bufferSize = 8040
Dim chunk = New Byte(bufferSize - 1) {}
Dim retCount As Long
Dim startIndex As Long = 0
retCount = oSqlDataReader.GetBytes(1, startIndex, chunk, 0, bufferSize)
While retCount = bufferSize
context.Response.BinaryWrite(chunk)
startIndex += bufferSize
retCount = oSqlDataReader.GetBytes(1, startIndex, chunk, 0, bufferSize)
End While
oSqlDataReader.Close()
oSqlConnection.Close()
Dim actualChunk = New Byte(retCount - 2) {}
Buffer.BlockCopy(chunk, 0, actualChunk, 0, CInt(retCount) - 1)
context.Response.BinaryWrite(actualChunk)
End If
End Sub
非常感谢
I am trying to implement an ihttphandeler for streaming files. files may be tiny thumbnails or gigantic movies
the binaries r stored in sql server
i looked at a lot of code online but something does not make sense
isn't streaming supposed to read the data piece by piece and move it over the line?
most of the code seems to first read the whole field from mssql to memory and then use streaming for the output writing
wouldn't it b more efficient to actually stream from disk directly to http byte by byte (or buffered chunks?)
heres my code so far but cant figure out the correct combination of the sqlreader mode and the stream object and the writing system
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.BufferOutput = False
Dim FileField=safeparam(context.Request.QueryString("FileField"))
Dim FileTable=safeparam(context.Request.QueryString("FileTable"))
Dim KeyField=safeparam(context.Request.QueryString("KeyField"))
Dim FileKey=safeparam(context.Request.QueryString("FileKey"))
Using connection As New SqlConnection(ConfigurationManager.ConnectionStrings("Main").ConnectionString)
Using command As New SqlCommand("SELECT " & FileField & "Bytes," & FileField & "Type FROM " & FileTable & " WHERE " & KeyField & "=" & FileKey, connection)
command.CommandType = Data.CommandType.Text
end using
end using
end sub
please be aware that this sql command also returns the file extension (pdf,jpg,doc...) in the second field of the query
thank you all very much
EDIT:
i managed to find some more code, and now the page shows up intermittently. sometimes it brings the pdf file and sometimes it does not
i cant understand the pattern here
i think that the main problem is when the request is from a different page and i click on "show in new tab" then it never worked. when i do "show in new window" it mostly works but not always.
btw. the code ALWAYS runs. never breaks or errors or anything like that. it runs like a good boy from start to end on each request
sometimes IE after a long time, gives me a message (from the new tab) "There is a problem with Adobe/Acrobat reader. Please exit Adobe Acrobat/Reader and try again."
what can the matter be?
heres my current code
Shared Sub ProccessMedia(ByVal context As HttpContext)
If CurPerson Is Nothing OrElse Not CurPerson.PersonExts.FirstOrDefault.LetAllFiles Then Exit Sub
context.Response.BufferOutput = False
Dim FileField = SafeParam(context.Request.QueryString("FileField"))
Dim FileTable = SafeParam(context.Request.QueryString("FileTable"))
Dim KeyField = SafeParam(context.Request.QueryString("KeyField"))
Dim FileKey = SafeParam(context.Request.QueryString("FileKey"))
Dim oSqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("Main").ConnectionString)
Dim oSqlCommand = New SqlCommand("SELECT " & FileField & "Type," & FileField & "Bytes FROM " & FileTable & " WHERE " & KeyField & "=" & FileKey, oSqlConnection)
oSqlConnection.Open()
Dim oSqlDataReader = oSqlCommand.ExecuteReader(CommandBehavior.SequentialAccess)
If oSqlDataReader.Read() Then
context.Response.ContentType = GetMIMEType(oSqlDataReader.GetString(0))
Dim bufferSize = 8040
Dim chunk = New Byte(bufferSize - 1) {}
Dim retCount As Long
Dim startIndex As Long = 0
retCount = oSqlDataReader.GetBytes(1, startIndex, chunk, 0, bufferSize)
While retCount = bufferSize
context.Response.BinaryWrite(chunk)
startIndex += bufferSize
retCount = oSqlDataReader.GetBytes(1, startIndex, chunk, 0, bufferSize)
End While
oSqlDataReader.Close()
oSqlConnection.Close()
Dim actualChunk = New Byte(retCount - 2) {}
Buffer.BlockCopy(chunk, 0, actualChunk, 0, CInt(retCount) - 1)
context.Response.BinaryWrite(actualChunk)
End If
End Sub
thank you very much
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
间歇性停止了。不知道为什么。
但现在工作正常
the intermittance has stopped. dont know why.
but now its working ok