2014-12-16 5 views
0

У меня проблема с чтением поля blob из базы данных, содержащей файл msword и сохраняющий его в файле (.doc/.docx). Что Мори это прекрасно работает в Delphi 2010, но в Delphi XE2 сохранены файлы invalid.This мой кодЧтение msword из blob-файла Delphi xe2

dane.SQLtmp.Close; 
dane.SQLtmp.SQL.Clear; 
dane.SQLtmp.SQL.Add('select wydruk,typ,IdWydruku from wydruki where nazwa=:d0'); 
dane.SQLtmp.Params[0].AsString:=name; 
dane.SQLtmp.Open; 

if dane.SQLtmp.RecordCount> 0 then 
begin 

t:=TMemoryStream.Create; 
t.Position:=0; 

TblobField(dane.sqltmp.FieldByName('wydruk')).saveToStream(T); 
T.SaveToFile('C:\FILE'+filetpe); 
t.Free; 
end; 

Сохранение файла в базе данных:

 dane.SQLtmp.Close; 
     dane.SQLtmp.SQL.Clear; 
     dane.SQLtmp.SQL.Add('insert into Wydruki (Nazwa,Operator,wydruk,opis,typ,rodzaj,podmiot,typsplaty,grupa,podgrupa)'); 
     dane.Sqltmp.SQL.Add('VALUES (:d0,:d1,:d2,:d3,:d4,:d5,:d6,:d7,:d8,:d9)'); 


dane.SQLtmp.Params[0].AsString:=NazwaPliku; //File name 
dane.SQLtmp.Params[1].AsInteger:=glowny.ID_operator; 

    t:=TMemoryStream.Create; 
     t.Position:=0; 
     t.LoadFromFile(OpenFile.FileName); 

     t.Position:=0; 

dane.sqltmp.Params[2].LoadFromStream(t,ftBlob); 
dane.SQLtmp.Params[3].AsString:=opis; 
dane.SQLtmp.Params[4].AsString:=typ;  // file type 
// . 
// . 
// . 
dane.SQLtmp.ExecSQL; 

В Delphi 2010 он работал ...:/

+0

Что такое 'filetpe'? –

+0

Тип файла, это может быть .doc/docx – Svenson

+0

Вы уверены, что используете правильный тип файла в соответствии с фактическими данными в блобе? Присвоение .docx в фактический файл .doc делает его недоступным для Word, в то время как он по-прежнему работает (при открытии с Word 2007, по крайней мере). –

ответ

3

Вам необходимо использовать TBlobField.CreateBlobStream и скопировать код TFileStream.

Согласно documentation:

Вызов CreateBlobStream, чтобы получить поток для чтения и записи значения поля, заданного параметром поля. Параметр Mode указывает, будет ли поток использоваться для чтения значения поля (bmRead), записи значения поля (bmWrite) или изменения значения поля (bmReadWrite).

Совет на той же странице документации говорит:

Совет: Предпочтительно называть CreateBlobStream вместо того, чтобы создавать поток блоб непосредственно в коде. Это гарантирует, что поток соответствует набору данных, а также может гарантировать, что наборы данных, которые не всегда хранят данные BLOB в памяти, извлекают данные blob перед созданием потока.

Пример кода на основе твоего выше:

var 
    Blob: TStream; 
    Strm: TFileStream; 
    BlobFld: TBlobField; 
begin 
    dane.SQLtmp.SQL.Text := 'select wydruk,typ,IdWydruku from wydruki where nazwa=:d0'; 
    dane.SQLtmp.Params[0].AsString:=name; 
    dane.SQLtmp.Open; 

    BlobFld := dane.SQLtmp.FieldByName('wydruk') as TBlobField; 
    Blob := dane.SQLtmp.CreateBlobStream(BlobFld, bmRead); 
    try 
    Strm := TFileStream.Create('C:\FILE' + filetpe, fmCreate); 
    try 
     Strm.CopyFrom(Blob, Blob.Size); 
    finally 
     Strm.Free; 
    end; 
    finally 
    Blob.Free; 
    end; 
end; 
+0

Я думаю, что вы прав, может быть, я должен вставить их (текстовые файлы) по-разному, чем в D10 – Svenson

+0

К сожалению, эффект тот же, только созданный файл 1 кб, и находится в странной кодировке. Возможно, я должен сохранить файл в базе данных таким же образом. Можете ли вы показать мне, как – Svenson

+0

Это будет второй (отдельный) вопрос, но вы можете понять это. Откройте файл в потоке, создайте поток blob и скопируйте из потока файлов в поток blob. (Это полностью противоположно коду в моем ответе, просто отмените потоки и загрузите поток файлов из файла на диске.) –

0

Проблема была в компонентах Interbase (IB) в Хе2. Когда я изменил их на компоненты FireDac'c, мой и ваш код работают. Это интересно, недавно продукт embarcadero имеет много ошибок.

Смежные вопросы