Reading binary data from DAO (mdb) database

Reading binary data from DAO (mdb) database

Post by Ken Sutherlan » Wed, 10 Oct 2001 15:37:01



I realize this must get asked a lot, but...

How do I read binary data from a DAO (mdb) database?

I am trying to store thumbnail images. I am storing them as JPEG files. I
seem to be storing them in the database OK because the size of the mdb file
increases by the amount I would expect bases on the size of the JPEG
file(s).

My problem is on the other side, reading the binary data out of the database
and saving it to a JPEG file.

I don't want to use DFX, if I can possibly avoid it.

Here is what I am doing:

////////////////////////////////////////////////////////////////////////////
/

 CDaoDatabase* pDb = NULL;
 CDaoRecordset* pRecordset = NULL;
 CString str;

 // This may take a while...
 CWaitCursor wc;
 try {
  // Open the working dir file directory database.
  // Create the database, if it doesn't exist.
  pDb = pApp->OpenDirectoryDatabase(TRUE);        // NOTE: This is my
routine!
  if (!pDb)
   return;  // Oops!

  // Create a record set.
  pRecordset = new CDaoRecordset(pDb);
  pRecordset->Open(dbOpenSnapshot, "SELECT FileName, Thumbnail,
ThumbnailSize FROM Files");

  // OK! Loop through the records.
  m_nThumbnailCount = 0;
  while (!pRecordset->IsEOF()) {
   // Get the file name.
   COleVariant&var = pRecordset->GetFieldValue("FileName");
   str = CCrack::strVARIANT(var);
   TRACE("FileName = %s\n", str);

   // Copy out JPEG data.
   var = pRecordset->GetFieldValue("ThumbnailSize");
   int nSize = V_I4(&var);
   TRACE("Size = %i\n", nSize);

   var = pRecordset->GetFieldValue("Thumbnail");
   str = CCrack::strVARIANT(var);
   TRACE("Thumbnail = %s\n", str);

   CByteArray& rByteArray = (CByteArray&)var;
   TRACE("Array size = %i\n", rByteArray.GetSize());

   BYTE* pData = rByteArray.GetData();
   TRACE("pData = %08x\n", pData);

   pRecordset->MoveNext();
   m_nThumbnailCount++;
  }

  TRACE("Thumbnail count = %i\n", m_nThumbnailCount);
 }
 catch (CDaoException* e)
 {
  // Oops!
  DisplayDaoException(e);        // NOTE: This is my routine!
  e->Delete();
 }

//Cleanup:
 // Close the directory databse.
 TRACE("Closing the database\n");
 if (pRecordset != NULL) {
  if (pRecordset->IsOpen())
   pRecordset->Close();
  delete pRecordset;
 }

 pApp->CloseDirectoryDatabase();                // NOTE: This is my routine!

////////////////////////////////////////////////////////////////////////////
/

The TRACE looks something like this:

FileName = SomeFile.AVI
Size = 3617
Thumbnail = Array of VT_UI1
Array size = 1497936
pData = 00000000

So it is correctly reading the AVI file name and the size of the JPEG file,
which I am storing explicitly. But it doesn't seem to be reading the binary
JPEG data correctly.

I came across the following code by going to
"http://groups.google.com/advanced_group_search" and searching
"comp.os.ms-windows.programmer.tools.mfc" for the words "DAO binary"

////////////////////////////////////////////////////////////////////////////
/

#define BLOCKSIZE 1024
void CFieldArchive::AddFile(CString FileName)
{
 CFile In(FileName, CFile::modeRead | CFile::shareDenyNone);
 long FileLength = In.GetLength();
 (*this)<<FileLength;
 long Retrieved=0;
 char *Buffer = (char *)malloc(BLOCKSIZE);
 COleVariant x;
 x.vt = VT_BSTR;
 do {
  Retrieved=In.Read(Buffer, BLOCKSIZE);
  if (Retrieved > 0){
   x.bstrVal = SysAllocStringByteLen(Buffer, Retrieved);
   Field->AppendChunk(x);
   SysFreeString(x.bstrVal);
  }
 } while (Retrieved==BLOCKSIZE); free(Buffer);

Quote:}

////////////////////////////////////////////////////////////////////////////
/

What I really need is the corresponding "CFieldArchive::SpitOut(CString
FileName)" routine. I have tried to compile the above code by deriving
CFieldArchive from CArchive, but what is "Field"? Does anyone have the
complete code, or something like it?

--
Ken Sutherland

http://www.j-mac.co.jp/
http://www.voicenet.co.jp/~ken

 
 
 

Reading binary data from DAO (mdb) database

Post by VK » Sun, 14 Oct 2001 12:02:35


Hi,

You can beat me up, but the first thing I can think of is to remove '&' from
CByteArray& rByteArray = (CByteArray&)var;

Sorry, I don't have MSDN right now but if that won't work drop me a line,
we'll figure it out.


Quote:> I realize this must get asked a lot, but...

> How do I read binary data from a DAO (mdb) database?

> I am trying to store thumbnail images. I am storing them as JPEG files. I
> seem to be storing them in the database OK because the size of the mdb
file
> increases by the amount I would expect bases on the size of the JPEG
> file(s).

> My problem is on the other side, reading the binary data out of the
database
> and saving it to a JPEG file.

> I don't want to use DFX, if I can possibly avoid it.

> Here is what I am doing:

////////////////////////////////////////////////////////////////////////////

- Show quoted text -

Quote:> /

>  CDaoDatabase* pDb = NULL;
>  CDaoRecordset* pRecordset = NULL;
>  CString str;

>  // This may take a while...
>  CWaitCursor wc;
>  try {
>   // Open the working dir file directory database.
>   // Create the database, if it doesn't exist.
>   pDb = pApp->OpenDirectoryDatabase(TRUE);        // NOTE: This is my
> routine!
>   if (!pDb)
>    return;  // Oops!

>   // Create a record set.
>   pRecordset = new CDaoRecordset(pDb);
>   pRecordset->Open(dbOpenSnapshot, "SELECT FileName, Thumbnail,
> ThumbnailSize FROM Files");

>   // OK! Loop through the records.
>   m_nThumbnailCount = 0;
>   while (!pRecordset->IsEOF()) {
>    // Get the file name.
>    COleVariant&var = pRecordset->GetFieldValue("FileName");
>    str = CCrack::strVARIANT(var);
>    TRACE("FileName = %s\n", str);

>    // Copy out JPEG data.
>    var = pRecordset->GetFieldValue("ThumbnailSize");
>    int nSize = V_I4(&var);
>    TRACE("Size = %i\n", nSize);

>    var = pRecordset->GetFieldValue("Thumbnail");
>    str = CCrack::strVARIANT(var);
>    TRACE("Thumbnail = %s\n", str);

>    CByteArray& rByteArray = (CByteArray&)var;
>    TRACE("Array size = %i\n", rByteArray.GetSize());

>    BYTE* pData = rByteArray.GetData();
>    TRACE("pData = %08x\n", pData);

>    pRecordset->MoveNext();
>    m_nThumbnailCount++;
>   }

>   TRACE("Thumbnail count = %i\n", m_nThumbnailCount);
>  }
>  catch (CDaoException* e)
>  {
>   // Oops!
>   DisplayDaoException(e);        // NOTE: This is my routine!
>   e->Delete();
>  }

> file://Cleanup:
>  // Close the directory databse.
>  TRACE("Closing the database\n");
>  if (pRecordset != NULL) {
>   if (pRecordset->IsOpen())
>    pRecordset->Close();
>   delete pRecordset;
>  }

>  pApp->CloseDirectoryDatabase();                // NOTE: This is my
routine!

////////////////////////////////////////////////////////////////////////////

- Show quoted text -

Quote:> /

> The TRACE looks something like this:

> FileName = SomeFile.AVI
> Size = 3617
> Thumbnail = Array of VT_UI1
> Array size = 1497936
> pData = 00000000

> So it is correctly reading the AVI file name and the size of the JPEG
file,
> which I am storing explicitly. But it doesn't seem to be reading the
binary
> JPEG data correctly.

> I came across the following code by going to
> "http://groups.google.com/advanced_group_search" and searching
> "comp.os.ms-windows.programmer.tools.mfc" for the words "DAO binary"

////////////////////////////////////////////////////////////////////////////

- Show quoted text -

Quote:> /

> #define BLOCKSIZE 1024
> void CFieldArchive::AddFile(CString FileName)
> {
>  CFile In(FileName, CFile::modeRead | CFile::shareDenyNone);
>  long FileLength = In.GetLength();
>  (*this)<<FileLength;
>  long Retrieved=0;
>  char *Buffer = (char *)malloc(BLOCKSIZE);
>  COleVariant x;
>  x.vt = VT_BSTR;
>  do {
>   Retrieved=In.Read(Buffer, BLOCKSIZE);
>   if (Retrieved > 0){
>    x.bstrVal = SysAllocStringByteLen(Buffer, Retrieved);
>    Field->AppendChunk(x);
>    SysFreeString(x.bstrVal);
>   }
>  } while (Retrieved==BLOCKSIZE); free(Buffer);
> }

////////////////////////////////////////////////////////////////////////////

- Show quoted text -

> /

> What I really need is the corresponding "CFieldArchive::SpitOut(CString
> FileName)" routine. I have tried to compile the above code by deriving
> CFieldArchive from CArchive, but what is "Field"? Does anyone have the
> complete code, or something like it?

> --
> Ken Sutherland

> http://www.j-mac.co.jp/
> http://www.voicenet.co.jp/~ken


 
 
 

Reading binary data from DAO (mdb) database

Post by Ken Sutherlan » Tue, 16 Oct 2001 14:00:23


I tried that, actually,

    CByteArray theByteArray = (CByteArray)var;

But I get a compile error:

    error C2440: 'type cast' : cannot convert from 'class CByteArray' to
'class COleVariant'

I've had a look at 'Technote: Improved Conformance to ANSI C++', but I can't
figure out what I should do!


Quote:> Hi,

> You can beat me up, but the first thing I can think of is to remove '&'
from
> CByteArray& rByteArray = (CByteArray&)var;

> Sorry, I don't have MSDN right now but if that won't work drop me a line,
> we'll figure it out.