简体   繁体   中英

Delphi XE8 Datasnap Server returning and freeing TStream

I'm using this datasnap servermethod to transfer an image:

function TServerMethods.DownloadFile(sFilePath: string): TStream;
var
  strFileStream: TFileStream;
begin
  GetInvocationMetadata.ResponseContentType := 'image/jpeg';
  strFileStream := TFileStream.Create(sFilePath, fmOpenRead);
  Result := strFileStream;
end;

This works ok, BUT it seems that the created stream is never freed! When I try to delete the file I get an "file in use error". It is the same problem when I return a selfwritten class; the destructor is never called. Do I have to enable something?

This is what i did to fix it, it is workaround but it at least work.
1. Instred of returning file stream I return TStream, and i use modification of function IsFileInUse

    Files.IsFileInUse(path); //Check if file is used and try to free it

    fs := TFileStream.Create(path, fmOpenRead or fmShareDenyNone);
    fs.Position := 0;

    RecordSize := SizeOf(Measurements);
    StreamSize := fs.Size;
    j := (StreamSize div RecordSize) - 1;

    result := TMemoryStream.Create();

    for i := 0 to j do
    begin
      result.CopyFrom(fs, RecordSize);
    end;

    FreeAndNil(fs);

    //result := TFileStream.Create(path, fmOpenRead or fmShareDenyNone);
    result.Position := 0; 

2. On client application first time it download file but second time it stuck with exception. So do try exc inside try exc repeating same call 2 times. It look like 1 call rase exception on download file call but it also free Stream so second call work every time.

  try
    try
      fs := TFileStream.Create(FilePath + RecordFileNameAPI, fmCreate);

  st := TMemoryStream.Create();
  st := APIClientModule.ServerMethodsBlob.getRecordingbyId(RecordFileNameAPI);
  st.Position := 0;

  RecordSize := SizeOf(Measurements);
  StreamSize := st.Size;
  j := (StreamSize div RecordSize) - 1;

  setlength(MeasurementArrayAPI, j + 1);

  // Copy Stream to memory object
  for i := 0 to j do
  begin
    st.Read(Measurements, RecordSize);
    MeasurementArrayAPI[i] := Measurements;
  end;

  // Copy Stream to File
  st.Position := 0;
  for i := 0 to j do
  begin
    fs.CopyFrom(st, RecordSize);
  end;

Except
  begin
    try
      FreeAndNil(fs);
      FreeAndNil(st);
      fs := TFileStream.Create(FilePath + RecordFileNameAPI, fmCreate);

      st := TMemoryStream.Create();
      st := APIClientModule.ServerMethodsBlob.getRecordingbyId(RecordFileNameAPI);
      st.Position := 0;

      RecordSize := SizeOf(Measurements);
      StreamSize := st.Size;
      j := (StreamSize div RecordSize) - 1;

      setlength(MeasurementArrayAPI, j + 1);

      // Copy Stream to memory object
      for i := 0 to j do
      begin
        st.Read(Measurements, RecordSize);
        MeasurementArrayAPI[i] := Measurements;
      end;

      // Copy Stream to File
      st.Position := 0;
      for i := 0 to j do
      begin
        fs.CopyFrom(st, RecordSize);
      end;
    Except
      exc := true;
    end;
  end;

end;

  finally  
    FreeAndNil(fs);  
    FreeAndNil(st);

if(not exc) then
begin
 //APIClientModule.ServerMethodsBlob.completeDownloding();

  if Assigned(FonGetLastRecordingDataAPIFinihed) then
    FonGetLastRecordingDataAPIFinihed();
end;


end;

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