我有一个SqlDataReader,需要使用SqlDataReader.GetBytes()方法从中读取varbinary(max)列。此方法填充字节数组,因此需要知道要读取的数据长度。
这是我感到困惑的地方。显然我想读取这行/列中从数据库返回的所有数据,那么我应该通过什么'length'参数?
据我所知,SqlDataReader没有提供任何方法来发现可用的数据长度,因此这种方法对我来说似乎很尴尬。
我很想在这里传递int.MaxValue并忘掉这个问题,但有些事情并不适合我。
我知道我可以改为呼叫
byte[] value = (byte[])dataReader["columnName"];
..这似乎完全在内部处理长度问题。但是,我正在使用一组围绕SqlDataReader.GetXXXX()方法构建的复杂代码生成模板。所以我被绑在使用GetBytes并且需要了解它的正确用法。
答案 0 :(得分:33)
处理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*
的现有代码 - 在这种情况下,强制转换方法非常合适。
答案 1 :(得分:1)
你可能会这样做。在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;
}
}