下载大文件,保存在数据库中

我们有很多文件,在SQL Server数据库中保存为二进制文件。 我已经将用于传递这些文件的.ashx文件发送给用户。 不幸的是,当文件变得相当大时,它将失败,并出现以下错误:

算术运算中溢出或下溢

我假设它耗尽了内存,因为我将二进制文件加载到byte []中。

所以,我的问题是,当它来自数据库表时,我怎样才能创建这个function,读取块(也许?)? 似乎Response.TransmitFile()似乎是一个不错的选择,但同样,如何使用数据库?

DB.GetReposFile()在下面的代码中从数据库中获取文件。 条目有各种字段:Filename,ContentType,datestamps和FileContent as varbinary。

这是我的function,提供文件:

context.Response.Clear(); try { if (!String.IsNullOrEmpty(context.Request.QueryString["id"])) { int id = Int32.Parse(context.Request.QueryString["id"]); DataTable dtbl = DB.GetReposFile(id); string FileName = dtbl.Rows[0]["FileName"].ToString(); string Extension = FileName.Substring(FileName.LastIndexOf('.')).ToLower(); context.Response.ContentType = ReturnExtension(Extension); context.Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName); byte[] buffer = (byte[])dtbl.Rows[0]["FileContent"]; context.Response.OutputStream.Write(buffer, 0, buffer.Length); } else { context.Response.ContentType = "text/html"; context.Response.Write("

Need a valid id

"); } } catch (Exception ex) { context.Response.ContentType = "text/html"; context.Response.Write("

" + ex.ToString() + "

"); }

更新:我最终得到的function是下面列出的function。 Tim提到,DB.GetReposFileSize()只获取内容Datalength。 我在原始代码中调用此函数,而不是这两行:

 byte[] buffer = (byte[])dtbl.Rows[0]["FileContent"]; context.Response.OutputStream.Write(buffer, 0, buffer.Length); 

新下载function:

 private void GetFileInChunks(HttpContext context, int ID) { //string path = @"c:\somefile.txt"; //FileInfo file = new FileInfo(path); int len = DB.GetReposFileSize(ID); context.Response.AppendHeader("content-length", len.ToString()); context.Response.Buffer = false; //Stream outStream = (Stream)context.Response.OutputStream; SqlConnection conn = null; string strSQL = "select FileContent from LM_FileUploads where ID=@ID"; try { DB.OpenDB(ref conn, DB.DatabaseConnection.PDM); SqlCommand cmd = new SqlCommand(strSQL, conn); cmd.Parameters.AddWithValue("@ID", ID); SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess); reader.Read(); byte[] buffer = new byte[1024]; int bytes; long offset = 0; while ((bytes = (int)reader.GetBytes(0, offset, buffer, 0, buffer.Length)) > 0) { // TODO: do something with `bytes` bytes from `buffer` context.Response.OutputStream.Write(buffer, 0, buffer.Length); offset += bytes; } } catch (Exception ex) { throw ex; } finally { DB.CloseDB(ref conn); } } 

您可以使用DATALENGTH来获取VARBINARY的大小,并使用SqldataReader其流式传输,并使用Read -or ReadBytes

看看这个答案,看看实现: 在ASP.NET中流式传输文件的最佳方式