简体   繁体   中英

Delphi - Compress TStringList with ZLib and save to SQL VARBINARY column

I need to take the values from a TStringList, compress it using the System.ZLIb libraries and save it to a SQL Server database as a VARBINARY(MAX) column.

Thus far I have was able to read the compressed data from the SQL table, uncompress it, and load it into a TStringList. However, saving the data back to the database is where my problem lies and I cannot get it to work. According to the Embarcadero docwiki, this should be a very simple process: http://docwiki.embarcadero.com/CodeExamples/Sydney/en/ZLibCompressDecompress_(Delphi)

Here is the code to update my SQL table. When I get to the "CompressedStrm.CopyFrom(InputStream, InputStream.Size);" line, I get a "Stream read error" error.

procedure TdmMain.SaveSystemSetting(SettingName: string; Settings: TStringList);
var
  InputStream, OutputStream: TMemoryStream;
  CompressedStrm: TCompressionStream;
begin
  InputStream:= TMemoryStream.Create;
  OutputStream:= TMemoryStream.Create;
  try
    Settings.SaveToStream(InputStream, TEncoding.Default);

    CompressedStrm := TCompressionStream.Create(clDefault, OutputStream);
    try
      CompressedStrm.CopyFrom(InputStream, InputStream.Size);
      OutputStream.SaveToFile('c:\output.zip');
    finally
      FreeAndNil(CompressedStrm);
    end;

    {save settings to the database}
    qryWork.Close;
    qryWork.SQL.Clear;
    qryWork.SQL.Add('UPDATE SystemSettings');
    qryWork.SQL.Add('   SET Setting = :data');
    qryWork.SQL.Add(' WHERE SettingName = ''' + SettingName + '''');
    qryWork.Parameters.ParamByName('data').LoadFromStream(OutputStream, ftBlob);
    qryWork.ExecSQL;
  finally
    FreeAndNil(InputStream);
    FreeAndNil(OutputStream);
  end;
end;

The following code reads from the db, decompress the data and load the TStringList - it works 100%:

procedure TdmMain.GetSystemSetting(SettingName: string; var Settings: TStringList);
var
  SettingBlob: TBlobField;
  DecompStream: TDecompressionStream;
  InputStream, OutputStream: TMemoryStream;
begin
  qryWork.Close;
  qryWork.SQL.Clear;
  qryWork.SQL.Add('SELECT Setting');
  qryWork.SQL.Add('  FROM SystemSettings');
  qryWork.SQL.Add(' WHERE SettingName = ''' + SettingName + '''');
  qryWork.Open;
  if not qryWork.EOF then
  begin
    SettingBlob := qryWork.FieldByName('Setting') as TBlobField;

    InputStream := TMemoryStream.Create;
    OutputStream := TMemoryStream.Create;
    try
      SettingBlob.SaveToStream(InputStream);
      InputStream.Position := 0;

      DecompStream := TDecompressionStream.Create(InputStream);
      try
        OutputStream.CopyFrom(DecompStream, 0);
        OutputStream.Position := 0;
        Settings.LoadFromStream(OutputStream, TEncoding.Default);
      finally
        FreeAndNil(DecompStream);
      end;
    finally
      FreeAndNil(InputStream);
      FreeAndNil(OutputStream);
    end;
  end;
  qryWork.Close;
end;

Forgot to reposition the input stream...

  try
    Settings.SaveToStream(InputStream, TEncoding.Default);
    InputStream.Position := 0;
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM