0

ファイルのダウンロード機能を持つ WCF サービスを作成する必要があります。この WCF は、Delphi アプリケーションによって使用されます。

問題: ダウンロードされるファイルが非常に大きく、Delphi 側でメモリの問題が発生する可能性があります。これまでのところ、私はこのコードを持っています:

[OperationContract]
byte[] DownloadFile(string filePath);

ただし、このコードにより、クライアント アプリがすべてのデータをメモリ内に保持するため、問題が発生する可能性があります。

方法: ストリーミングを有効にする方法を参照してください

しかし、MSDN から切り取られたこのコードについて質問があります。

[OperationContract]
Stream GetStream(string data);

クライアント側では、関数に a を渡したいですTFileStream。すべてのバイト読み取りを使用TFileStreamすると、ディスクに直接移動します。しかし、関数はストリームを返しますが、ストリームは関数のパラメーターではないため、私が望むことはできません。

WCF サービスからディスクに直接ファイルをダウンロードするにはどうすればよいですか?

4

2 に答える 2

5

他の (.NET 以外の) クライアントを操作するときに、WCF の "組み込み" ストリーミング機能に依存すると、奇妙な問題が発生する大きな原因になることがわかりました...

基本的に、次のように定義することで、この種のシナリオを解決します。

[OperationContract]
string DownloadFile(string filePath);

このメソッドは HTTP(S) URL を生成し、それを返します...

このようにして、http対応のクライアントは堅牢な方法でデータを操作できます...

これにより、サーバーが少し複雑になることに注意してください。これは、URL を生成する (および HTTP GET を提供する) メカニズムが必要になるためです (セキュリティ、「グローバルに」一意、限られた時間のみ使用可能など)。

しかし、大きな利点は、HTTP サポートが利用可能である限り、そこにあるクライアント (モバイルまたはいくつかの奇妙な組み込みデバイス、または遭遇する可能性のあるもの) がこのスキームを実装できることです (Delphi には非常に優れた http クライアント オプションがいくつかあります)。 .

于 2012-05-30T14:57:37.603 に答える
2

まず、Delphi 2010 でストリーミング WCF サービスをまったく利用できるかどうかはわかりません。利用できる場合、次のように動作します。

WCF サービスはストリーミング サービスである必要があります。つまり、バインディングの を または に設定する必要transferModeありStreamedますStreamedResponse。文字列をパラメーターとして渡したい場合は、 にする必要がありますStreamedResponse。それ以外の場合は、パラメーターもストリームにする必要があります。

ストリーム サービスがあるということは、ストリームまたは を返さないメソッドが存在しないことも意味しますvoid。例えば、ストリーミングサービスの場合、以下の2つの方式を同一サービス内に持つことはできません。

Stream GetStream(string s);
int GetInteger(string s);

また、次のものを持つことはできません。

Stream GetStream(string s);

Streamedパラメータもストリームでなければならないため、 に設定されているサービスでは。

Streamメソッドがパラメーターを受け取るようにしても、「埋められる」ストリームでメソッドを呼び出すことはできません。Streamその時点で実際のインスタンスがやり取りされるのではなく、コンテンツが実際にコピーされて戻されます。前方へ。

Delphi では、メソッド呼び出しの結果としてストリームを取得します。TFileStream次に、ソースが Delphi の別のストリームである場合と同様に、そのストリームの内容を にコピーできます。そのためのコードはググることができます。基本的に、アドリアーノは機能するはずのものを投稿しました。基本的に: ソース ストリームから読み取り、すべての読み取りと書き込みが完了するまで宛先ストリームに書き込むか、次のようなことを試すことができます。

stream1 := wcfServiceClient.GetTheStream();
try
    stream2:= TFileStream.Create('to.txt', fmCreate);
    try
        stream2.CopyFrom(stream1, stream1.Size);
    finally
        stream2.Free;
    end;
finally
    stream1.Free;
end;

繰り返しますが、これは、C# または VB.NET からアクセスする場合と同様に、Delphi から WCF ストリーミング サービスにアクセスできるという前提の下でのみ機能します。

于 2012-05-30T14:43:48.517 に答える