Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TBlobByteData [D7, FireBird_2.1]


checkmate-maker ©   (2008-11-20 17:34:00) 

Здравствуйте, уважаемые знатоки и мастера Delphi.
 Помогите, пожалуйста, со следующей проблемой:
 Использую подключение к серверу FB_2.1. Использую компоненты InterBase. Следующий код
lFileLength := FIBQuery.GetBlobFieldData(aFieldId + 1, lBlobByteData);
         if (lFileLength > 0) then
           if not WriteFile(hFile, lBlobByteData, lFileLength, lNumberOfBytesWritten, nil) then
             ShowMessage('GetLastError = ' + IntToStr(GetLastError));
возвращает сообщение GetLastError = 1784. При выполнении lFileLength = 47208; lBlobByteData заполняется числами, что неудивительно, ведь тип TBlobByteDataобъявлен как array of Byte

 Посмотрел в MSDN код ошибки: The supplied user buffer is not valid for the requested operation. - думаю Вы в переводе не нуждаетесь, но я нуждаюсь в разрешении этой ситуации.
 MSDN советует выполнять CancelIo(hFile)- выражение у меня выполнилось(возвратило True), а вот ошибка при сохранении данных в файл не исчезла.

 Всем спасибо за участие.


Сергей М.   (2008-11-20 19:55:00) [1]


> lBlobByteData заполняется числами, что неудивительно, ведь
> тип TBlobByteData объявлен как array of Byte


Любопытное рассуждение)


Johnmen   (2008-11-20 19:48:00) [2]


>  lBlobByteData заполняется числами, что неудивительно, ведь
> тип TBlobByteData объявлен как array of Byte

Спасибо, поржал.


Leonid Troyanovsky   (2008-11-20 19:01:00) [3]


> PEAKTOP ©   (20.11.08 18:18) [1]

>  Result := false;


Лишнее - функция всегда вернет true (не так ли?).

>    FreeAndNil(StrmSrc);

Много лишнего: StrmSrc.Free; // пишите короче - Вы ж не Гоголь ;)
(и, во-ще, FreeAndNil - это ж популизм борланда).

--
Regards, LVT.


PEAKTOP   (2008-11-20 18:18:00) [4]

У тебя БЛОБ скорее всего текстовый (имеется в виду, как он создан в базе, а не как тебе захотелось объявить его в Delphi). Или потомок от него. А значит, - IBX не годится для работы. Эта проблема возникла с Firebird 2.0 и началом сборки его на MSVC 2005 (ранее собирали на MSVC 7.0). Связано это с различием в API функциях InterBase (на который заточен IBX) и Firebird.
(Если кому вдруг интересно, то при получении текстовых данных, сервер возвращает в младшем байте XSQLVAR::sqlsubtype идентификатор кодовой страницы этих данных, в отличие от InterBase).
То есть размер буфера возвращается (вот здесь точно не помню) или в символах, или в байтах, в то время как Delphi приложение ждет размер в байтах.  А размер "в символах" не равен размеру "в байтах" (вспоминаем, UNICODE_FSS). Отсюда вывод, что либо
1) база создана в UNICODE_FSS
2) база создана в NONE
3) чарсет базы не равен чарсету подключения.

Путь решения: переделывать сохранение из базы на TFileStream и оперировать данными как потоком байтов, не вдаваясь в дебри.

function SaveToFile(DataSet :TIBCustomdataSet; const FieldName, FileName:TFileName):Boolean;
var
 StrmSrc  :TStream;
 StrmDest :TFileStream;
begin
 Result := false;
 try
   StrmSrc := DataSet.CreateBlobStream(DataSet.FindField(FieldName), bmRead);
   StrmSrc.Seek(0, soFromBeginning);
   StrmDest := TFileStream.Create(FileName, fmCreate);
   StrmDest.CopyFrom(StrmSrc, StrmSrc.Size);
 finally
   FreeAndNil(StrmSrc);
   FreeAndNil(StrmDest);
   Result := true;
 end;
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо