![]() |
Filestream Segmente über WebService machen Exe kaputt andere
Hallo zusammen,
ich will Dateien über einen WebService austauschen. Auf WebserviceSeite gibt es zum Speichern und Laden der Dateien die Methoden
Deren Code so aussieht:
Delphi-Quellcode:
Die Client Seite verwendet diese Methoden wie folgt:
function DoSaveToFile (Datei : Thfs_Datei) : String;
var todatei: TFilestream; filename : String; begin todatei := nil; filename := HelenFSuri (Datei.Dir + Datei.Name); if filename = '' then result := '404 Directory not found' else try if Datei.SegmentNr = 0 then If FileExists (filename) and not Datei.Replace then result := '301 File exists' else todatei := TFileStream.Create (filename, fmCreate or fmOpenWrite) else todatei := TFileStream.Create (filename, fmOpenWrite); if todatei <> nil then begin if Datei.SegmentNr > 1 then {Böser Fehler!!!} todatei.Seek (Datei.SegmentNr * Datei.SegmentSize, soBeginning); todatei.Write (Datei.data[0], Length (Datei.data)); todatei.Free; result := filename + ' - ' + IntToStr (Datei.SegmentNr) + '/' + IntToStr(Datei.SegmentMax); end; except on e : Exception do result := e.Message; end; end; function DoLoadFromFile (var Datei : Thfs_Datei) : String; var FDatei : TFilestream; data : TDateiDaten; filename : String; len : Integer; begin result := ''; filename := HelenFSuri (Datei.Dir + Datei.name); if filename <> '' then begin FDatei := TFileStream.Create (FileName, fmOpenRead); if Datei.SegmentNr = 0 then Datei.SegmentMax := FDatei.Size Div Datei.SegmentSize + 1; if FDatei.Size > ((Datei.Segmentnr) * Datei.SegmentSize) then begin if Datei.SegmentNr > 0 then FDatei.Seek ((Datei.Segmentnr) * Datei.SegmentSize, soBeginning); if (FDatei.Size - FDatei.Position) < Datei.SegmentSize then if (FDatei.Size - FDatei.Position) > 0 then len := FDatei.Size - FDatei.Position else len := 0 else len := Datei.SegmentSize; SetLength (data, len); if len > 0 then FDatei.ReadBuffer (data[0], len); Datei.data := data; Datei.SegmentNr := Datei.SegmentNr + 1; end else begin SetLength (data, 0); Datei.data := data; end; result := filename + ' - ' + IntToStr (Datei.SegmentNr) + '/' + IntToStr(Datei.SegmentMax); end; end;
Delphi-Quellcode:
Das Object Thfs_Datei und der TDatei Array sehen so aus:
//Download
procedure TForm1.Button2Click(Sender: TObject); var Datei : Thfs_Datei; PhysFile : TFileStream; begin If SaveDialog1.Execute then begin Datei := Thfs_Datei.Create; Datei.SegmentNr := 0; Datei.Name := ExtractFilename (Edit1.Text); Datei.Dir := Extractfilepath (Edit1.Text); Datei.SegmentSize := 1024; PhysFile := TFileStream.Create (SaveDialog1.Filename, fmCreate); repeat Memo1.Lines.Add (GetIHFS_web_cgi.DoLoadFile(Datei)); Application.ProcessMessages; Sleep(100); PhysFile.Write(Datei.Data[0], Length(Datei.Data)); until Datei.SegmentNr >= Datei.SegmentMax; PhysFile.Free; Datei.Free; end; end; //Upload procedure TForm1.Button1Click(Sender: TObject); var Datei : Thfs_Datei; PhysFile : TFileStream; data : TDateiDaten; len : Integer; error : String; begin if Opendialog1.Execute then begin Datei := Thfs_Datei.Create; PhysFile := TFileStream.Create(Opendialog1.FileName, fmOpenRead); Datei.Name := ExtractFileName (OpenDialog1.FileName); Datei.Dir := '/'; Datei.SegmentNr := 0; Datei.SegmentSize := 2048; Datei.SegmentMax := PhysFile.Size div Datei.SegmentSize + 1; Datei.Replace := false; error := ''; while (Datei.SegmentNr <= Datei.SegmentMax) do begin if (PhysFile.Size - PhysFile.Position) < Datei.SegmentSize then if (PhysFile.Size - PhysFile.Position) > 0 then len := PhysFile.Size - PhysFile.Position else len := 0 else len := Datei.SegmentSize; SetLength (data, len); if Len > 0 then PhysFile.Read(data[0], len); Datei.data := data; error := GetIHFS_web_cgi.DoSaveFile (Datei); if (Datei.SegmentNr = 1) and (Pos('301', error) > -1) then If MessageDlg ('Datei überschreiben?', mtWarning, [mbyes, mbno], 0) = mrYes then begin Datei.Replace := true; error := GetIHFS_web_cgi.DoSaveFile (Datei); end else exit; Datei.SegmentNr := Datei.SegmentNr + 1; Memo1.Lines.Add (error); end; PhysFile.Free; Datei.Free; end; end;
Delphi-Quellcode:
Wenn ich Dateien (alles ohne .exe) übertrage funktioniert das Prinzip ohne Probleme, egal wie groß die Datei ist.
TDateiDaten = array of byte;
Thfs_Datei = class(TRemotable) private FDir: string; FName: string; FReplace: Boolean; FSegmentSize: Integer; _checksum: string; _data: TDateiDaten; _SegmentMax: Integer; _SegmentNr: Integer; published property checksum: string read _checksum write _checksum; property data: TDateiDaten read _data write _data; property Dir: string read FDir write FDir; property Name: string read FName write FName; property Replace: Boolean read FReplace write FReplace; property SegmentMax: Integer read _SegmentMax write _SegmentMax; property SegmentNr: Integer read _SegmentNr write _SegmentNr; property SegmentSize: Integer read FSegmentSize write FSegmentSize; end; Will ich allerdings Anwendungen (alles mit .exe) übertragen, stimmen zwar am Ende die Dateigrößen, aber es sind keine ausführbaren Anwendungen mehr. Wieso nicht? |
Re: Filestream Segmente über WebService machen Exe kaputt an
übeträgst du ascii oder binary? beim ftp macht das anscheinend was aus, ka ob das bei deiner anwendung auch so ist.
|
Re: Filestream Segmente über WebService machen Exe kaputt an
Hallo,
da ich die Daten mit einem FileStream auslese und in einem Array of byte zwischenlagere, gehe ich davon aus, das die Übertragung binär abläuft. Vorallem, da SOAP die Objecte korrekt umwandeln müsste. |
Re: Filestream Segmente über WebService machen Exe kaputt an
ok... war ja nur ne vage vermutung ;)
|
Re: Filestream Segmente über WebService machen Exe kaputt an
Diese bösen kleinen Fehlerteufelchen :twisted:
Wenn wir den Quelltext genau betrachten, fällt auf, das die Datei-Segment-Nummer bei 0 beginnt. In der Methode DoSaveToFile steht:
Delphi-Quellcode:
Folglich wird das 0. Segment an den Anfang geschrieben, das erste Segment an den Anfang geschrieben, das zweite Segment dahinter geschrieben, das dritte Segment dahinter geschrieben ... *Wir könnten dies noch bis ins unendliche fortführen*
if Datei.SegmentNr > 1 then
todatei.Seek (Datei.SegmentNr * Datei.SegmentSize, soBeginning); Wenn ich das 0. Segment mit dem Ersten überschreibe, kann doch keine vernünftige Datei herauskommen. Ich frage mich nur, warum das bei ZIP Archiven, Bildern, etc nicht aufgefallen ist... Vielen Dank, DGL-luke für das Treten in die richtige Richtung :smile: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz