Форум: "Начинающим";
Текущий архив: 2009.01.04;
Скачать: [xml.tar.bz2];
ВнизTBlobByteData Найти похожие ветки
← →
checkmate-maker (2008-11-20 17:34) [0]Здравствуйте, уважаемые знатоки и мастера Delphi.
Помогите, пожалуйста, со следующей проблемой:
Использую подключение к серверу FB_2.1. Использую компоненты InterBase. Следующий кодlFileLength := FIBQuery.GetBlobFieldData(aFieldId + 1, lBlobByteData);
возвращает сообщение GetLastError = 1784. При выполнении lFileLength = 47208; lBlobByteData заполняется числами, что неудивительно, ведь тип TBlobByteData объявлен как array of Byte
if (lFileLength > 0) then
if not WriteFile(hFile, lBlobByteData, lFileLength, lNumberOfBytesWritten, nil) then
ShowMessage("GetLastError = " + IntToStr(GetLastError));
Посмотрел в 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;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.004 c