Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.01.04;
Скачать: CL | DM;

Вниз

TBlobByteData   Найти похожие ветки 

 
checkmate-maker   (2008-11-20 17:34) [0]

Здравствуйте, уважаемые знатоки и мастера 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), а вот ошибка при сохранении данных в файл не исчезла.

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


 
PEAKTOP ©   (2008-11-20 18:18) [1]

У тебя БЛОБ скорее всего текстовый (имеется в виду, как он создан в базе, а не как тебе захотелось объявить его в 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;


 
Leonid Troyanovsky ©   (2008-11-20 19:01) [2]


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

>  Result := false;


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

>    FreeAndNil(StrmSrc);

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

--
Regards, LVT.


 
Johnmen ©   (2008-11-20 19:48) [3]


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

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


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


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


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



Страницы: 1 вся ветка

Текущий архив: 2009.01.04;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.01 c
15-1225441518
Vlad Oshin
2008-10-31 11:25
2009.01.04
Работа. Программиста никому не надо? :)


2-1227258981
parasolka
2008-11-21 12:16
2009.01.04
TColorDialog


2-1227604826
Чайник.Становление ч1
2008-11-25 12:20
2009.01.04
Delfi работа с Word


2-1227668527
Riply
2008-11-26 06:02
2009.01.04
Гарантия записи в реестр.


2-1227463627
Nastya
2008-11-23 21:07
2009.01.04
Создание у уничтожение компонентов в RunTime