1

私はasp.net Webサービスを持っています。この Web サービスの一部の機能は、最初にクライアントの要求を解凍することです。このために、私は 2 つのメソッドを作成しました。1 つはMemoryStreamを使用し、もう 1 つはFileStreamを使用します。

MemoryStreamを使用すると、 OutofMemoryExceptionが発生することがあります。このため、MemoryStream の代わりに FileStream を使用する予定です。

これを使用する前に、私は正しい仕事のために正しいことをしていることを明確にする必要があります.

N:B:クライアントが10MB以上のデータを Web サービスに送信することがありますが、これを Web サービス側で解凍する必要があります。200 以上のクライアントを実行しています。Webサービスがホストされている場所には、30を超えるWebアプリケーションとWebサービスもホストされていますが、私のWebサービスは別のアプリプールの下にあります。

私は見ました: GZIP 解凍 C# OutOfMemory

私はそこからある程度の知識を得ることができますが、Webサービスについては、私の状況に基づいてかなり混乱しています。これについて明確に理解する必要があります。

Decompress メソッド (MemoryStream を使用) は以下のとおりです。

public static string Decompress(string compressedText)
        {
            try
            {
                byte[] gzBuffer = Convert.FromBase64String(compressedText);
                using (MemoryStream ms = new MemoryStream())
                {
                    int msgLength = BitConverter.ToInt32(gzBuffer, 0);
                    ms.Write(gzBuffer, 4, gzBuffer.Length - 4);

                    byte[] buffer = new byte[msgLength];

                    ms.Position = 0;
                    using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
                    {
                        zip.Read(buffer, 0, buffer.Length);
                    }

                    return Encoding.UTF8.GetString(buffer);
                }
            }
            catch (Exception ex)
            {
                DataSyncLog.Debug(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType + "::" + System.Reflection.MethodBase.GetCurrentMethod().ToString() + ":" + ex.ToString()+" : "+ex.StackTrace);
            }

            return string.Empty;
        }

Decompress メソッド (FileStream を使用) は以下のとおりです。

public static string Decompress(string compressedText)
        {
            string SourceDirectory = System.Guid.NewGuid().ToString();
            string DestinationDirectory = System.Guid.NewGuid().ToString();
            try
            {
                File.WriteAllBytes(SourceDirectory, Convert.FromBase64String(compressedText));
                using (FileStream fd = File.Create(DestinationDirectory))
                {
                    using (FileStream fs = File.OpenRead(SourceDirectory))
                    {
                        fs.Seek(4, 0);

                        using (Stream csStream = new GZipStream(fs, CompressionMode.Decompress))
                        {

                            byte[] buffer = new byte[1024];

                            int nRead;

                            while ((nRead = csStream.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                fd.Write(buffer, 0, nRead);
                            }
                        }
                    }
                }

                return Encoding.UTF8.GetString(File.ReadAllBytes(DestinationDirectory));
            }
            catch (Exception ex)
            {
                DataSyncLog.Debug(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType + "::" + System.Reflection.MethodBase.GetCurrentMethod().ToString() + ":" + ex.ToString() + " : " + ex.StackTrace);
                return string.Empty;
            }
            finally
            {
                ClearFiles(SourceDirectory);
                ClearFiles(DestinationDirectory);
            }
        }

どちらを使用すべきか、またはこのエラーを克服できる MemoryStream を使用するメソッドに必要な変更について、正しい方向性を教えてください。これまたはコード変更の提案について明確に理解していただければ幸いです。

4

1 に答える 1

1

ストリームでの作業は、2 番目のケースではメモリに関してより効率的に見えます。メモリ ストリームではストリーム全体をメモリに保持し、ファイル ストリームでは制限されたサイズのバッファのみを保持します。

どちらのメソッドも、署名が原因でメモリに問題が発生する可能性があります。クライアントが 10MB を送信すると、この量のメモリが compressText 引数と戻り値に割り当てられます。

サービスのインターフェイスの変更を調べることができるため、データはチャンクで転送されます (ここでは、同様のアプローチの例を見つけることができます - http://www.codeproject.com/Articles/43272/Uploading-Large-Files-Through-Web-サービス)

または、WCF への切り替えを検討できる場合は、ストリーミング転送モードをサポートしています - http://msdn.microsoft.com/en-us/library/ms751463.aspx

于 2013-10-03T12:59:32.807 に答える