什么'长度'参数应该传递给SqlDataReader.GetBytes()

时间:2012-06-21 09:26:50

标签: c# .net vb.net ado.net sqldatareader

我有一个SqlDataReader,需要使用SqlDataReader.GetBytes()方法从中读取varbinary(max)列。此方法填充字节数组,因此需要知道要读取的数据长度。

这是我感到困惑的地方。显然我想读取这行/列中从数据库返回的所有数据,那么我应该通过什么'length'参数?

据我所知,SqlDataReader没有提供任何方法来发现可用的数据长度,因此这种方法对我来说似乎很尴尬。

我很想在这里传递int.MaxValue并忘掉这个问题,但有些事情并不适合我。

我知道我可以改为呼叫

byte[] value = (byte[])dataReader["columnName"];

..这似乎完全在内部处理长度问题。但是,我正在使用一组围绕SqlDataReader.GetXXXX()方法构建的复杂代码生成模板。所以我被绑在使用GetBytes并且需要了解它的正确用法。

2 个答案:

答案 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

Or this one

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;
            }
           }