.net IHTTPHandler 流式 SQL 二进制数据

发布于 2024-09-03 11:04:17 字数 3273 浏览 1 评论 0原文

我正在尝试为流文件实现 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 有问题。请退出 Adob​​e 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

呆头 2024-09-10 11:04:17

间歇性停止了。不知道为什么。

但现在工作正常

the intermittance has stopped. dont know why.

but now its working ok

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文