Results 1 to 12 of 12

Thread: het zippen van een stream

  1. #1

    het zippen van een stream

    Hallo, ondanks dat er hierover al eerder een topic is geweest kom ik er toch niet helemaal uit.
    Ik wil graag met TzipFile streams in en uit pakken

    In mijn test programma "download" ik een stream uit mijn database (is een blob)
    Deze stream wil ik dan inpakken om daarna ook in mijn database op te slaan.
    Echter zodra ik zip stream open met het ZIP component krijg ik een foutmelding
    "Tstream.seek not implemented"

    Kortom ik doe iets verkeerd maar ik heb geen flauw idee wat.
    Heeft iemand hier ervaring mee?

    Code:
    var sql:string;
    OrgStream:Tstream;
    ZipStream:Tstream;
    Zip:TZipFile;
    LocalHeader: TZipHeader;
    begin
     sql:= 'select * from data where index = '+ indexnr.ToString;
     firebirdDB.query_open(sql);
     OrgStream:=FireBirdDB.query.createblobstream(FireBirdDB.query.Fieldbyname('waveform_data'),bmread);
     label1.Caption:= 'Org file size =  '+(OrgStream.Size/1000).ToString + 'kB';
    
     Zip:=TZipFile.Create;
    
     ZipStream:=Tstream.Create;
    
     Zip.Open(Zipstream,zmwrite);
     Zip.Add(OrgStream,LocalHeader);
     zip.Close;
    
     label2.Caption:= 'Org file size =  '+(ZipStream.Size/1000).ToString + 'kB';
    
     Zip.Free;
     OrgStream.Free;
     ZipStream.Free;

  2. #2
    Dit is het probleem
    ZipStream:=Tstream.Create;

    Tstream is geen volledig geïmplementeerde stream-class die je zo kunt gebruiken. Niet alle functies zijn geïmplementeerd zoals seek.

    Je zult dus tmemorystream of tfilestream moeten gebruiken.

    Dus
    ZipStream:=Tmemorystream.Create;
    (De variabeledeclaratie kun je wel op tstream laten staan)

  3. #3
    Thanks, dat verklaart een hoop.
    Helaas loop ik nu bij de volgende stap vast.
    wanneer ik de Add functie uitvoer krijg de foutmelding Item not found.
    Dit komt doordat de LocalHeader niet is ingevuld, maar ik zou niet weten hoe ik deze zou moeten vullen

  4. #4
    Add heeft voor stream ook een volgende definitie.
    procedure Add(Data: TStream; const ArchiveFileName: string; Compression: TZipCompression = zcDeflate; AExternalAttributes: TFileAttributes = []); overload;

    Dus zip.add(stream, 'filename') zou voldoende moeten zijn. (De andere parameters zijn optioneel)

  5. #5
    Yep hiermee werkt het.
    Haal nu een nette factor 3 op de file grootte, iets minder dan met winrar maar dat is marginaal
    Straks even kijken of we ook de andere kant op kunnen.
    Zodra die code werkt zal ik deze hier posten

  6. #6
    Senior Member Wok's Avatar
    Join Date
    Dec 2002
    Location
    Alkmaar
    Posts
    2,085
    Hogere compressie geeft meestal een langere verwerkingstijd.
    Je zal een compromis moeten vinden tussen size en snelheid.
    Als beide belangrijk zijn zou je kunnen overwegen om de stream zonder compressie op te slaan en deze later op een idle moment in een treat alsnog te compressen
    10.4.2, Delphi2010, of Lazarus 2.2.0

  7. #7
    Zoals belooft hierbij de code voor het zippen en unzippen van een stream
    In mijn geval is de verwerkingstijd geen issue het gaat om relatief kleine bestanden (maar wel vele kleintjes) die na een meting opgelsagen moeten worden
    Voor het uitpakken geldt het zelfde het is maar 1 klein bestand dat verwerkt hoeft te worden.

    Code:
    var sql:string;
    OrgStream:Tstream;
    ZipStream:Tstream;
    UnzipStream:Tstream;
    ms :TMemorystream;
    Zip:TZipFile;
    LocalHeader: TZipHeader;
    begin
     sql:= 'select * from Axial_data where pijp_nr = '+ Pijpnr.ToString;
     firebirdDB.query_open(sql);
     OrgStream:=FireBirdDB.query.createblobstream(FireBirdDB.query.Fieldbyname('waveform_data'),bmread);
     label1.Caption:= 'Org file size =  '+(OrgStream.Size/1000).ToString + 'kB';
    
     Zip:=TZipFile.Create;
    
     ZipStream:=TMemorystream.Create;
    
     Zip.Open(Zipstream,zmwrite);
     Zip.Add(OrgStream,'test');
     zip.Close;
    
     label2.Caption:= 'Zipped file size =  '+(ZipStream.Size/1000).ToString + 'kB';
    
     UnZipStream:=TMemorystream.Create;
     ZipStream.Position:=0;
    
     try
      Zip.Open(ZipStream, zmReadWrite);
      Zip.Read(0, UnzipStream, localHeader);
      Zip.Close;
     except
      on E: EZipException do
      begin
        showmessage('geen zip bestand');
        UnzipStream.Position:=0;
        UnzipStream.CopyFrom(OrgStream);
      end
    
     end;
    
     label3.Caption:= 'UnZipped file size =  '+(UnZipStream.Size/1000).ToString + 'kB';
    
     Zip.Free;
     OrgStream.Free;
     ZipStream.Free;
     UnzipStream.Free;

  8. #8
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    Ah! Ik had al een paar keer geprobeerd om unzip to stream werkend te krijgen maar het lukte maar niet..... en... eh.. nu weer niet?! Bij het compilen blijf ik een error krijgen:

    Zip.Read(0,UnZipStream,localheader) => [dcc32 Error] u_ziptst_01.pas(66): E2250 There is no overloaded version of 'Read' that can be called with these arguments

    unzipstream, localheader zijn netjes gedeclareerd, de hints bij de argumenten geven keurig aan wat het is ... ik kom er maar niet achter wat ik fout doe...wat kan er hier mis zijn?

    ( Delphi XE7, WIN10)

  9. #9
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    Oeps... ..als ik Unzipstream niet als tmemorystream declareer maar als tStream ( maar vervolgens wel een UbZipstream:=tmemorystream.create gebruik) dan gaat het wel goed ....kan iemand uitleggen waarom dat zo is?
    a

  10. #10
    Heb je met die aanpassing niet ook wat parameters omgegooid? Of heeft TZipFile.Read misschien een overload die specifiek een TMemoryStream accepteert?
    1+1=b

  11. #11
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    is het niet omdat de ZIPfile.read een tStream vraagt en een tMemorystream een afgeleide daarvan is? Ik gebruik eigenlijk altijd automatisch een tMemorystream als er iets van een stream wordt gevraagd een beetje in de veronderstelling dan alle basis eigenschappen vanzelf meekomen maar klaarblijkelijk wordt er iets overridden.

  12. #12
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    (winrar zal je nooit halen, omdat die archives vaak solid zijn. Je kan dan niet individuele files decomprimeren zonder de files ervoor ook te decomprimeren. Een doendelijk mogelijk alternatief daarvoor is eerst een TAR stream bouwen (b.v. met de tar stream component van destructor.de, en die dan te zippen. (of nog liever te lzmaen of bzip2en)

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •