Главная страница
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.013 c
15-1226179709
Труп Васи Доброго
2008-11-09 00:28
2009.01.04
Займите WMR


3-1212563525
allucard
2008-06-04 11:12
2009.01.04
Database not assigned


15-1226050249
cosinus
2008-11-07 12:30
2009.01.04
Посоветуйте книгу


15-1225861996
Slider007
2008-11-05 08:13
2009.01.04
С днем рождения ! 5 ноября 2008 среда


9-1176153590
Morpheuz
2007-04-10 01:19
2009.01.04
Создание водной поверхности средствами GLScene