DocBytes = m_DataReader.GetValue(i) as byte[];
这将创建一个大小为 DATA_LENGTH(column_name) 的缓冲区,
然后将其完整复制到您的 MemoryStream。
当 DATA_LENGTH(column_name) 值很大时,这很糟糕。
您需要通过缓冲区将其复制到内存流。
此外,如果您的文件太大,请将其写入临时文件,而不是将其完整存储在 MemoryStream 中。
我就是这样做的
// http://stackoverflow.com/questions/2885335/clr-sql-assembly-get-the-bytestream
// http://stackoverflow.com/questions/891617/how-to-read-a-image-by-idatareader
// http://stackoverflow.com/questions/4103406/extracting-a-net-assembly-from-sql-server-2005
public static void RetrieveFileStream(System.Data.IDbCommand cmd, string columnName, string path)
{
using (System.Data.IDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.SequentialAccess | System.Data.CommandBehavior.CloseConnection))
{
bool hasRows = reader.Read();
if (hasRows)
{
const int BUFFER_SIZE = 1024 * 1024 * 10; // 10 MB
byte[] buffer = new byte[BUFFER_SIZE];
int col = string.IsNullOrEmpty(columnName) ? 0 : reader.GetOrdinal(columnName);
int bytesRead = 0;
int offset = 0;
// Write the byte stream out to disk
using (System.IO.FileStream bytestream = new System.IO.FileStream(path, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
{
while ((bytesRead = (int)reader.GetBytes(col, offset, buffer, 0, BUFFER_SIZE)) > 0)
{
bytestream.Write(buffer, 0, bytesRead);
offset += bytesRead;
} // Whend
bytestream.Close();
} // End Using bytestream
} // End if (!hasRows)
reader.Close();
} // End Using reader
} // End Function RetrieveFile
采用此代码写入 memoryStream 很简单。
也许您需要使缓冲区大小更小或更大。
public static System.IO.MemoryStream RetrieveMemoryStream(System.Data.IDbCommand cmd, string columnName, string path)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
using (System.Data.IDataReader reader = cmd.ExecuteReader(System.Data.CommandBehavior.SequentialAccess | System.Data.CommandBehavior.CloseConnection))
{
bool hasRows = reader.Read();
if (hasRows)
{
const int BUFFER_SIZE = 1024 * 1024 * 10; // 10 MB
byte[] buffer = new byte[BUFFER_SIZE];
int col = string.IsNullOrEmpty(columnName) ? 0 : reader.GetOrdinal(columnName);
int bytesRead = 0;
int offset = 0;
// Write the byte stream out to disk
while ((bytesRead = (int)reader.GetBytes(col, offset, buffer, 0, BUFFER_SIZE)) > 0)
{
ms.Write(buffer, 0, bytesRead);
offset += bytesRead;
} // Whend
} // End if (!hasRows)
reader.Close();
} // End Using reader
return ms;
} // End Function RetrieveFile
如果您需要将其放入 Response.OutputStream,请考虑直接将其写入其中,而不是通过 MemoryStream.ToArray() + WriteBytes。