我有一个SqlDataReader,需要使用SqlDataReader.GetBytes()方法从中读取VARBINARY(max)列。 此方法填充字节数组,因此需要知道读什么数据的长度。
这是我感到困惑。显然我要阅读所有已经从数据库中该行/列返回的数据有啥“长度”参数我要传递?
据我所看到的,SqlDataReader中没有提供任何方法来发现数据的长度是可用的,所以这种方法似乎相当尴尬的我。
我很想只是传递int.MaxValue这里,忘记这个问题,但一些关于这个不正确的坐我。
我知道我可以改为调用
byte[] value = (byte[])dataReader["columnName"];
..这似乎完全照顾长度问题的内部。 但是我有一组已遍布SqlDataReader.GetXXXX()方法构建复杂的代码生成模板工作。 所以我绑成使用GetBytes会和需要了解它的正确使用。
当处理varbinary(max)
,有两种情况:
GetBytes()
是用于第二个方案,当您使用CommandBehaviour.SequentialAccess
,以确保您的流媒体数据,而不是进行缓冲 。 特别是,在这种用法,你通常会被在写码流(例如),在一个循环。 例如:
// moderately sized buffer; 8040 is a SQL Server page, note
byte[] buffer = new byte[8040];
long offset = 0;
int read;
while((read = reader.GetBytes(col, offset, buffer, 0, buffer.Length)) > 0) {
offset += read;
destination.Write(buffer, 0, read); // push downstream
}
然而! 如果使用的是中等大小的数据,那么你原来的代码:
byte[] data = (byte[])reader[col];
是好的! 。 有什么不对这种方法,而事实上Get*
API 在少数情况下破 - GetChar()
是一个著名的例子(提示:它不工作)。
不要紧 ,你有现有的使用代码Get*
-在这种情况下,中投的做法是完全恰当的。
你也许可以做到这一点。 发现在MSDN上。 也许它可以服务器你的目的
// Reset the starting byte for the new BLOB.
startIndex = 0;
// Read the bytes into outbyte[] and retain the number of bytes returned.
retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);
// Continue reading and writing while there are bytes beyond the size of the buffer.
while (retval == bufferSize)
{
bw.Write(outbyte);
bw.Flush();
// Reposition the start index to the end of the last buffer and fill the buffer.
startIndex += bufferSize;
retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);
}
// Write the remaining buffer.
bw.Write(outbyte, 0, (int)retval - 1);
bw.Flush();
http://msdn.microsoft.com/en-us/library/87z0hy49%28v=vs.71%29.aspx#Y132
或者这一个
int ndx = rdr.GetOrdinal("<ColumnName>");
if(!rdr.IsDBNull(ndx))
{
long size = rdr.GetBytes(ndx, 0, null, 0, 0); //get the length of data
byte[] values = new byte[size];
int bufferSize = 1024;
long bytesRead = 0;
int curPos = 0;
while (bytesRead < size)
{
bytesRead += rdr.GetBytes(ndx, curPos, values, curPos, bufferSize);
curPos += bufferSize;
}
}