4

DataSnapサーバー/クライアント間でいくつかの大きなストリーム(〜1Mb)を転送しようとしていますが、役に立ちません。ジム・ティアニー( http://blogs.embarcadero.com/jimtierney/2009/04/06/31461 )のコードをうまく理解しようとしていますが、ライブラリがないためにコードをコンパイルすることさえできません。とりあえず ...

私が受信できるストリームの最大サイズは64kなので、私のような週末のプログラマーに提供できるヒント/アイデア/コードサンプルは大歓迎です。ありがとうございました!

私のサーバーコード:

function TsrvMethods.getStream(iCount: integer): TStream;
begin
  Result := dummyStream('0123456789', iCount);
end;

function dummyStream(sCnt: string; iCount: integer): TStream;
begin
  Result := TMemoryStream.Create;
  while iCount > 1 do begin
    Result.Write(Pointer(sCnt)^, Length(sCnt));
    Dec(iCount);
  end;
  Result.Seek(0, TSeekOrigin.soBeginning);
end;

私のクライアントの呼び出しコード:

procedure TfrmMain.butStreamClick(Sender: TObject);
var
  sStr : TStream;
begin
  cycleConnection; //make sure we have an active connection

  with TsrvMethodsClient.Create( SQLConn.DBXConnection, False ) do begin
    sStr := getStream( Integer(SpinCount.Value) );
    Free;
  end;
  FreeAndNil(sStr);
end;
4

1 に答える 1

6

実際、私はそれを手に入れたと思います。私はこれを答えとして投稿しています。おそらく他の誰かがこれを必要としています。

procedure TfrmMain.butStreamClick(Sender: TObject);
const
  iBufSize = 128;
var
  sStr : TStream;
  sMem : TMemoryStream;
  buf: PByte;
  iRead: integer;
begin
  cycleConnection;

  with TsrvMethodsClient.Create( SQLConn.DBXConnection, False ) do begin

    sStr := getStream( 500000 ); //500k stream

    GetMem(buf, iBufSize);
    sMem := TMemoryStream.Create;
    try
      repeat
        iRead := sStr.Read( Pointer(buf)^, iBufSize);

        if iRead > 0 then sMem.WriteBuffer( Pointer(buf)^, iRead);
        if iRead < iBufSize then break;
      until iRead < iBufSize;
    finally
      FreeMem(buf, iBufSize);
    end;

    Free;
  end;
  FreeAndNil(sStr);
  FreeAndNil(sMem);
end;

PS

DataSnap コード サンプルを検索すると、1 つの (速度関連の) 改善点は、iBufSize を 61440 (または同等の 16 進数値 $F000) に設定することであることがわかりました。これは、一度に受信できる最大サイズと思われます。受信ストリームがより大きい場合、報告されるサイズは -1 になり、ストリーム全体を読み取るには上記のコードが必要です。

于 2009-11-22T19:32:19.270 に答える