TCP ServerとMemoryStreams / ByteArrayとして定義
-
18-09-2019 - |
質問
私はそれに送られたPOSTデータを処理するC#で書かれたTCPサーバーを持っています。現在、それは(1ギガバイトよりすなわち大きい)大量のデータをそれに送信されていない限り、それは(I)のリストDTOの中間で(バイトのアレイとしてメモリに全てを格納する)メモリの不足正常に動作します。大きなファイルの場合は、今私は、ディスクへのダウンストリーム、その後、それをディスクからストリーミングすることを意図して周りのファイル名を渡します。
現在、私のルーチンの全ては後知恵で、少し近視眼的だった、バイト配列を期待して書かれています。私はただのMemoryStreamのByteArrayを変換する場合は、メモリ使用量を倍増しますか?私は、ディスクからのストリームを読んでいるときのMemoryStreamに動作するように私のコードは私がそれを再利用することができます再書き込みと思いますか?
愚かな質問のため申し訳ありませんが、私はC#はデータのコピーを取るか、それが参照を取るとき時に必ず決して思いません。
解決
あなたはbyte[]
にMemoryStream
を渡すと、それは(コンストラクタで)最初にデータをコピーしますが、限り、あなたはbyte[]
を離すと、それはゴミを収集することができます。本質的に何も(あなたがで開始する正しくサイズを設定し、Stream
ではなくbyte[]
に直接書き込むことができます場合は特に)、「倍増」はありません。
私は完全にStream
への切り替えと言うだろう(しかしをのAPIでのみの利用Stream
- 何もmoerの特定、あなたがかかるのコードはどのタイプかを知る必要はありません)。あなたはインプロセスでバッファリングしたい場合に最も重要なのは、あなたがNetworkStream
を使用するように選択することができます(あなたがディスクにバッファリングする場合)またはFileStream
(ソケットから直接読み取るために)、またはMemoryStream
。また、あなたは、ストリームベースのコードを介してデータのボリュームを読むことを確認する必要があります。反復子ブロック(yield return
)は(Enumerable
を除いて、OrderBy
など、バッファする)ことができるLINQのGroupBy
方法として、ここでは非常に有用であることができる。
どちらbyte[]
を渡したりStream
を渡すと、彼らは、参照型をしているように、コピーされますし、何も原因となる - 。コピーされた唯一のものは、基準である(4または8バイトのx86 / x64のに依存します)。
他のヒント
A MemoryStreamをバイト配列の周りだけストリームラッパーであるので、あなたはそれを使って何を得ることはありません。
あなたは(少なくとも大きなファイルのために)行うために必要なものは、FileStreamを開いており、その中に自分のデータをダンプします。低レベルでは、あなたの接続からXバイトを読んで、あなたのファイルストリームにその直後に記述する必要があります。あなたが一度にメモリにフルギガわずか数バイトに引っ張っされることはありませんこの方法です。
これが行うのは簡単だろうかどうかは、あなたのTCPサーバーが符号化された方法によって異なります。
あなたがコピーするたびに対処することがありますREFキーワードを指定せずに関数に渡すと、バイトは、値型ですので。あなたはREFキーワードでそれを渡すと、それが本来のバイト配列への参照を取るよ。
のMemoryStreamは、参照型であるので、あなたのメモリ使用量がそれを使用すると倍増しませんので、それはデータをコピーしませんが、あなたはそのデータへの参照を中心に渡している。