Einzelnen Beitrag anzeigen

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