다음을 통해 공유


이진 데이터 획득

기본적으로 DataReader 는 전체 데이터 행을 사용할 수 있는 즉시 들어오는 데이터를 행으로 로드합니다. 그러나 BLOB(Binary Large Objects)은 단일 행에 포함될 수 없는 기가바이트의 데이터를 포함할 수 있으므로 다른 처리가 필요합니다. Command.ExecuteReader 메서드에는 CommandBehavior의 기본 동작을 수정하기 위해 인수를 사용하는 오버로드가 있습니다. SequentialAccess 메서드에 전달 하여 데이터 행을 로드하는 대신 데이터를 수신할 때 순차적으로 로드하도록 DataReader의 기본 동작을 수정할 수 있습니다. BLOB 또는 기타 큰 데이터 구조를 로드하는 데 적합합니다. 이 동작은 데이터 원본에 따라 달라질 수 있습니다. 예를 들어 Microsoft Access에서 BLOB을 반환하면 BLOB이 수신될 때 순차적으로 로드되지 않고 메모리에 로드되는 전체 BLOB이 로드됩니다.

SequentialAccess를 사용하도록 DataReader를 설정하는 경우 반환된 필드에 액세스하는 시퀀스를 주의해야 합니다. 사용 가능한 한 빨리 전체 행을 로드하는 DataReader의 기본 동작을 사용하면 다음 행을 읽을 때까지 순서에 따라 반환되는 필드에 액세스할 수 있습니다. 그러나 SequentialAccess를 사용하는 경우 DataReader 에서 반환된 필드에 순서대로 액세스해야 합니다. 예를 들어 쿼리가 BLOB인 세 개의 열을 반환하는 경우 세 번째 필드의 BLOB 데이터에 액세스하기 전에 첫 번째 및 두 번째 필드의 값을 반환해야 합니다. 첫 번째 또는 두 번째 필드 앞의 세 번째 필드에 액세스하는 경우 첫 번째 및 두 번째 필드 값을 더 이상 사용할 수 없습니다. 이는 SequentialAccess가 데이터를 순서대로 반환하도록 DataReader를 수정했으며 DataReader가 데이터를 읽은 후에는 데이터를 사용할 수 없기 때문입니다.

BLOB 필드의 데이터에 액세스할 때 데이터로 배열을 채우는 DataReaderGetBytes 또는 GetChars 형식 접근자를 사용합니다. 문자 데이터에 GetString을 사용할 수도 있습니다. 그렇지만. 시스템 리소스를 절약하려면 전체 BLOB 값을 단일 문자열 변수로 로드하지 않을 수 있습니다. 대신 반환할 데이터의 특정 버퍼 크기와 반환된 데이터에서 읽을 첫 번째 바이트 또는 문자의 시작 위치를 지정할 수 있습니다. GetBytesGetChars 는 반환된 바이트 또는 문자 수를 나타내는 값을 반환 long 합니다. GetBytes 또는 GetChars에 null 배열을 전달하는 경우 반환되는 긴 값은 BLOB의 총 바이트 또는 문자 수입니다. 데이터 읽기의 시작 위치로 배열 내 인덱스를 선택적으로 지정할 수 있습니다.

예시

다음 예제에서는 Microsoft SQL Server의 pubs 샘플 데이터베이스에서 게시자 ID 및 로고를 반환합니다. 게시자 ID(pub_id)는 문자 필드이고 로고는 BLOB인 이미지입니다. 로고 필드는 비트맵이므로 GetBytes를 사용하여 이진 데이터를 반환합니다. 필드가 순차적으로 액세스되어야 하므로 로고 앞의 현재 데이터 행에 대해 게시자 ID에 액세스합니다.

' Assumes that connection is a valid SqlConnection object.  
Dim command As SqlCommand = New SqlCommand( _  
  "SELECT pub_id, logo FROM pub_info", connection)  
  
' Writes the BLOB to a file (*.bmp).  
Dim stream As FileStream
' Streams the binary data to the FileStream object.  
Dim writer As BinaryWriter
' The size of the BLOB buffer.  
Dim bufferSize As Integer = 100
' The BLOB byte() buffer to be filled by GetBytes.  
Dim outByte(bufferSize - 1) As Byte
' The bytes returned from GetBytes.  
Dim retval As Long
' The starting position in the BLOB output.  
Dim startIndex As Long = 0
  
' The publisher id to use in the file name.  
Dim pubID As String = ""
  
' Open the connection and read data into the DataReader.  
connection.Open()  
Dim reader As SqlDataReader = command.ExecuteReader(CommandBehavior.SequentialAccess)  
  
Do While reader.Read()  
  ' Get the publisher id, which must occur before getting the logo.  
  pubID = reader.GetString(0)  
  
  ' Create a file to hold the output.  
  stream = New FileStream( _  
    "logo" & pubID & ".bmp", FileMode.OpenOrCreate, FileAccess.Write)  
  writer = New BinaryWriter(stream)  
  
  ' Reset the starting byte for a new BLOB.  
  startIndex = 0  
  
  ' Read bytes into outByte() and retain the number of bytes returned.  
  retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize)  
  
  ' Continue while there are bytes beyond the size of the buffer.  
  Do While retval = bufferSize  
    writer.Write(outByte)  
    writer.Flush()  
  
    ' Reposition start index to end of the last buffer and fill buffer.  
    startIndex += bufferSize  
    retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize)  
  Loop  
  
  ' Write the remaining buffer.  
  writer.Write(outByte, 0 , retval - 1)  
  writer.Flush()  
  
  ' Close the output file.  
  writer.Close()  
  stream.Close()  
Loop  
  
' Close the reader and the connection.  
reader.Close()  
connection.Close()  
// Assumes that connection is a valid SqlConnection object.  
SqlCommand command = new SqlCommand(  
  "SELECT pub_id, logo FROM pub_info", connection);  
  
// Writes the BLOB to a file (*.bmp).  
FileStream stream;
// Streams the BLOB to the FileStream object.  
BinaryWriter writer;
  
// Size of the BLOB buffer.  
int bufferSize = 100;
// The BLOB byte[] buffer to be filled by GetBytes.  
byte[] outByte = new byte[bufferSize];
// The bytes returned from GetBytes.  
long retval;
// The starting position in the BLOB output.  
long startIndex = 0;
  
// The publisher id to use in the file name.  
string pubID = "";
  
// Open the connection and read data into the DataReader.  
connection.Open();  
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);  
  
while (reader.Read())  
{  
  // Get the publisher id, which must occur before getting the logo.  
  pubID = reader.GetString(0);
  
  // Create a file to hold the output.  
  stream = new FileStream(  
    "logo" + pubID + ".bmp", FileMode.OpenOrCreate, FileAccess.Write);  
  writer = new BinaryWriter(stream);  
  
  // Reset the starting byte for the new BLOB.  
  startIndex = 0;  
  
  // Read bytes into outByte[] and retain the number of bytes returned.  
  retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);  
  
  // Continue while there are bytes beyond the size of the buffer.  
  while (retval == bufferSize)  
  {  
    writer.Write(outByte);  
    writer.Flush();  
  
    // Reposition start index to end of last buffer and fill buffer.  
    startIndex += bufferSize;  
    retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);  
  }  
  
  // Write the remaining buffer.  
  writer.Write(outByte, 0, (int)retval);  
  writer.Flush();  
  
  // Close the output file.  
  writer.Close();  
  stream.Close();  
}  
  
// Close the reader and the connection.  
reader.Close();  
connection.Close();  

참고하십시오