28

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

这就是我感到困惑的地方。显然我想读取从该行/列中的数据库返回的所有数据,那么我应该传递什么“长度”参数?

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

我很想在这里传递 int.MaxValue 并忘记这个问题,但是关于这个的一些事情并不适合我。

我知道我可以改为致电

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

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

4

2 回答 2

45

处理时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*在这种情况下,强制转换方法是非常合适的。

于 2012-06-21T09:48:36.653 回答
3

你可能会这样做。在 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;
            }
           }
于 2012-06-21T09:30:39.047 回答