AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Filestream Segmente über WebService machen Exe kaputt andere
Thema durchsuchen
Ansicht
Themen-Optionen

Filestream Segmente über WebService machen Exe kaputt andere

Ein Thema von webservice · begonnen am 17. Jul 2006 · letzter Beitrag vom 18. Jul 2006
Antwort Antwort
webservice

Registriert seit: 27. Jun 2006
3 Beiträge
 
Delphi 7 Professional
 
#1

Filestream Segmente über WebService machen Exe kaputt andere

  Alt 17. Jul 2006, 14:17
Hallo zusammen,

ich will Dateien über einen WebService austauschen. Auf WebserviceSeite gibt es zum Speichern und Laden der Dateien die Methoden
  • function DoSaveToFile (Datei : Thfs_Datei) : String;
  • function DoLoadFromFile (var Datei : Thfs_Datei) : String;

Deren Code so aussieht:
Delphi-Quellcode:
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;
Die Client Seite verwendet diese Methoden wie folgt:
Delphi-Quellcode:
//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;
Das Object Thfs_Datei und der TDatei Array sehen so aus:
Delphi-Quellcode:
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;
Wenn ich Dateien (alles ohne .exe) übertrage funktioniert das Prinzip ohne Probleme, egal wie groß die Datei ist.
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?
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Filestream Segmente über WebService machen Exe kaputt an

  Alt 17. Jul 2006, 14:19
übeträgst du ascii oder binary? beim ftp macht das anscheinend was aus, ka ob das bei deiner anwendung auch so ist.
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
webservice

Registriert seit: 27. Jun 2006
3 Beiträge
 
Delphi 7 Professional
 
#3

Re: Filestream Segmente über WebService machen Exe kaputt an

  Alt 17. Jul 2006, 14:54
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.
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Filestream Segmente über WebService machen Exe kaputt an

  Alt 17. Jul 2006, 14:55
ok... war ja nur ne vage vermutung
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
webservice

Registriert seit: 27. Jun 2006
3 Beiträge
 
Delphi 7 Professional
 
#5

Re: Filestream Segmente über WebService machen Exe kaputt an

  Alt 18. Jul 2006, 08:15
Diese bösen kleinen Fehlerteufelchen

Wenn wir den Quelltext genau betrachten, fällt auf, das die Datei-Segment-Nummer bei 0 beginnt.

In der Methode DoSaveToFile steht:
Delphi-Quellcode:
if Datei.SegmentNr > 1 then
   todatei.Seek (Datei.SegmentNr * Datei.SegmentSize, soBeginning);
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*

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
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz