1

我有一个 asp.net 网络服务。这个网络服务的一些功能是首先解压客户端请求。为此,我编写了 2 种方法,一种使用MemoryStream,另一种使用FileStream

当使用MemoryStream时,它会得到OutofMemoryException。因此,出于这个原因,我计划使用 FileStream 而不是 MemoryStream。

在使用它之前,我只需要澄清一下我正在为正确的工作做正确的事情。

N:B:有时我的客户会发送10MB+的数据到我需要在 web 服务端解压缩的 web 服务。我有超过200 个客户端在运行。在托管网络服务的地方,虽然我的网络服务位于不同的应用程序池下,但也托管了30 多个网络应用程序和网络服务。

我确实看到了:GZIP 解压 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 的方法进行任何修改,以克服这个错误。如果您对此或任何代码更改建议有清楚的了解,我将不胜感激。

4

1 回答 1

1

在第二种情况下,使用流在内存方面看起来更有效:使用内存流,您将整个流保存在内存中,使用文件流,您只有有限大小的缓冲区。

您的两种方法都可能因为它们的签名而存在内存问题:当客户端发送 10MB 时,此内存量将分配给压缩文本参数和返回值。

您可以查看更改服务的接口,因此数据以块的形式传输(在这里您可以找到类似方法的示例 - 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 回答