问题:WCF如何传输大文件

方案:主要有几种绑定方式netTcpbinding,basicHttpBinding,wsHttpbinding,设置相关的传输max消息选项,服务端和客户端都要设置,transferMode可以buffer,stream.

实例:netTcpbinding

直接代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.IO;
using System.Runtime.Serialization;

namespace FileWcfService
{
    [ServiceContract(Name="KuoFileUpload",Namespace="http://www.xinvu.com/")]
    public interface IFileUpload
    {

        [OperationContract]
        void Upload(byte[] file);

        //[OperationContract]   //此用于流模式
        //void UploadStream(FileMessage fileMessage);
    }

     
    //[MessageContract]
    //public class FileMessage
    //{
    //    [MessageHeader]
    //    public string FileName;

    //    [MessageBodyMember]
    //    public Stream FileData;
    //}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.IO;
using System.IO.Compression;

namespace FileWcfService
{
    [ServiceBehavior(Name = "MyFileUpload")]
    public class FileUpload : IFileUpload
    {
        public void Upload(byte[] file)
        {
            try
            {
                Console.WriteLine(file.Length);
                MemoryStream ms = new MemoryStream(file);
                GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress); 
                MemoryStream msTemp = new MemoryStream();
                gzip.CopyTo(msTemp);
                string path= @"E:\abc"+DateTime.Now.Ticks.ToString()+".rar";  //简单重命名
                Console.WriteLine(path);
                File.WriteAllBytes(path, msTemp.ToArray());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        //public void UploadStream(FileMessage fileMessage)
        //{
        //    string path = @"e:\" + fileMessage.FileName + DateTime.Now.Ticks.ToString() + ".rar";  // //简单重命名
        //    try
        //    { 
        //        FileStream fs = new FileStream(path, FileMode.CreateNew);
        //        fileMessage.FileData.CopyTo(fs);  
        //        fs.Flush();
        //        fs.Close(); 
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine(ex.Message);
        //    }
        //}
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace FileWcfService
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(FileUpload)))
            {
                if (host.State != CommunicationState.Opened)
                    host.Open();
                Console.WriteLine("服务已启动……");  
                Console.WriteLine();
                Console.Read();
            }
          
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.IO.Compression;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            DateTime date = DateTime.Now;
            FileUpload.KuoFileUploadClient file = new FileUpload.KuoFileUploadClient();
            byte[] buffer = this.FileUpload1.FileBytes;
            MemoryStream ms = new MemoryStream();
            GZipStream zip = new GZipStream(ms, CompressionMode.Compress);
            zip.Write(buffer, 0, buffer.Length);
            byte[] buffer_zip = ms.ToArray();
            zip.Close();
            ms.Close();
            //If the file bigger than 100MB, usually, there will be fault:
            //Failed to allocate a managed memory buffer of 208073270 bytes. The amount of available memory may be low.
            //I don't know how to salve this solution.So, please use stream mode.
            file.Upload(buffer_zip); 
            zip.Close();
            Response.Write(date.ToString() + "---" + DateTime.Now.ToString() + "<br/> Before:" + buffer.Length + ":After" + buffer_zip.ToString() + "<br/>");
            Response.Write(FileUpload1.FileName);


        }

        protected void Button2_Click(object sender, EventArgs e)
        {
            //DateTime date = DateTime.Now;
            //FileUpload.KuoFileUploadClient file = new FileUpload.KuoFileUploadClient(); 
             
            //FileUpload.FileMessage filedata = new FileUpload.FileMessage();

            //using (MemoryStream ms = new MemoryStream())
            //{   
            //    filedata.FileName = this.FileUpload1.FileName;
            //    filedata.FileData = this.FileUpload1.PostedFile.InputStream;
            //    file.UploadStream(filedata);
            //    Response.Write(date.ToString() + "---" + DateTime.Now.ToString() + "<br/>");
            //    Response.Write(FileUpload1.FileName);

            //}
        }
    }
}

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings> 
<!--
  流模式启用netTcpBindConfig,buffer启用netTcpBindingBuffer,人懒
--> <!--<netTcpBinding> <binding name="netTcpBindConfig" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Streamed" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647 " maxBufferSize="2147483647 " maxConnections="10" maxReceivedMessageSize="2147483647 " > <readerQuotas maxDepth="32" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> </security> </binding> </netTcpBinding>--> <netTcpBinding> <binding name="netTcpBindingBuffer" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647 " maxBufferSize="2147483647 " maxConnections="10" maxReceivedMessageSize="2147483647 " > <readerQuotas maxDepth="32" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> </security> </binding> </netTcpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="MyFileUpload"> <serviceMetadata /> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> <services> <service name="FileWcfService.FileUpload" behaviorConfiguration="MyFileUpload"> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:8089/FileService"/> </baseAddresses> </host> <!--<endpoint address="" binding="netTcpBinding" contract="FileWcfService.IFileUpload" bindingConfiguration="netTcpBindConfig" ></endpoint>--> <endpoint address="" binding="netTcpBinding" contract="FileWcfService.IFileUpload" bindingConfiguration="netTcpBindingBuffer" ></endpoint> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" ></endpoint> </service> </services> </system.serviceModel> </configuration>

 

 

实例二:basicHttpBinding ,实验上传1.5G没问题,局域网

新建一个web站点,加入一个wcf data service.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.IO;

namespace WcfService1
{
    // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
    [ServiceContract]
    public interface IGetDataService
    {
        [OperationContract]
        void UploadFile(FileData file);
    }
    [MessageContract]
    public class FileData
    {
        [MessageHeader]
        public string filename;
        [MessageBodyMember]
        public Stream data;
    }



}
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.IO;

namespace WcfService1
{
    public class GetDataService : IGetDataService
    {
        public void UploadFile(FileData file)
        {
            
            FileStream fs = new FileStream("D:\\" + file.filename, FileMode.OpenOrCreate);

            try
            {

                BinaryReader reader = new BinaryReader(file.data);

                byte[] buffer;

                BinaryWriter writer = new BinaryWriter(fs);
                long offset = fs.Length;
                writer.Seek((int)offset, SeekOrigin.Begin);

                do
                {

                    buffer = reader.ReadBytes(1024);

                    writer.Write(buffer);

                } while (buffer.Length > 0);

                fs.Close();
                file.data.Close();

            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            finally
            {

                fs.Close();
                file.data.Close();

            }

        }
    }
}
View Code

 

     protected void Button1_Click(object sender, EventArgs e)
        {
            FileData file = new FileData();
            file.filename = FileUpload1.FileName;
            file.data = FileUpload1.PostedFile.InputStream;
            GetDataService c = new GetDataService();
            c.UploadFile(file);
            Response.Write("文件传输成功!");
        }
View Code
<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
      <httpRuntime maxRequestLength="2147483647" />
  </system.web>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IGetDataService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="01:10:00" sendTimeout="01:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" transferMode="Streamed" useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:52884/mex" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGetDataService" contract="IGetDataService" name="BasicHttpBinding_IGetDataService" />
        </client>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /></system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
  </system.webServer>
  
</configuration>
View Code

 

posted on 2013-10-24 16:34  小草原  阅读(1212)  评论(0编辑  收藏  举报