内存流和文件流,在WebService中使用哪一个更适合用于GZipStream解压缩?

4
我有一个asp.net webservice。这个webservice的一些功能是首先解压缩客户端请求。为此,我编写了两种方法,一种使用MemoryStream,另一种使用FileStream。
使用MemoryStream时,有时会出现OutOfMemoryException。因此,出于这个原因,我计划改用FileStream。
在使用之前,我需要澄清一下是否做了正确的事情。
注意:有时我的客户端会向webservice发送10MB以上的数据,在webservice端我需要解压缩它们。我有200多个运行的客户端。webservice托管在30多个Web应用程序中,而且webservice也托管在不同的应用程序池下。
我看到了:GZIP decompression C# OutOfMemory
我从那里获得了一些知识,但对于Web服务,基于我的情况,哪一个更好我感到相当困惑。我需要对此有一个清晰的理解。

以下是解压缩方法(使用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;
        }

解压缩方法(使用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的方法进行任何修改以克服这个错误。如果您能为我提供清晰的理解或任何代码更改建议,我将非常感激。
1个回答

3
使用流的方式在内存方面更加高效:使用内存流,您将整个流保留在内存中,而使用文件流,则仅具有有限大小的缓冲区。
由于客户端发送10MB,因此这两种方法都可能存在内存问题,因为会为压缩文本参数和返回值分配该数量的内存。
您可以考虑更改服务的接口,以便数据以块的形式传输(在此处可以找到类似方法的示例 - http://www.codeproject.com/Articles/43272/Uploading-Large-Files-Through-Web-Service)。
或者,如果您可以考虑切换到WCF,则它支持流传输模式 - http://msdn.microsoft.com/en-us/library/ms751463.aspx

感谢@Alexey Zuev。首先,现在无法切换到WCF。我不理解这个链接。我没有通过Web服务传输大文件的问题。我的问题是在处理数据时,应该考虑哪种内存情况适合我的情况? - Rezoan
也许我有点理解这个链接了。你的意思是不需要额外的返回函数,直接在 Web 方法内处理(解压缩)请求,对吗? - Rezoan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接