[索引页]
[源码下载]
作者: webabcd
介绍
WCF(Windows Communication Foundation) - 消息处理:使用流数据传输文件,减少内存开销。
示例
1、服务
IStreamed.cs
Streamed.cs
2、宿主
Streamed.cs
App.config
3、客户端
Streamed.cs
App.config
运行结果:
上传文件后提示上传成功
OK
[源码下载]
[源码下载]
化零为整WCF(8) - 消息处理(使用流数据传输文件)
作者: webabcd
介绍
WCF(Windows Communication Foundation) - 消息处理:使用流数据传输文件,减少内存开销。
示例
1、服务
IStreamed.cs
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.IO;
namespace WCF.ServiceLib.Message
{
/// <summary>
/// 消息契约(定义与 SOAP 消息相对应的强类型类)
/// </summary>
[MessageContract]
public class FileWrapper
{
/// <summary>
/// 指定数据成员为 SOAP 消息头
/// </summary>
[MessageHeader]
public string FilePath;
/// <summary>
/// 指定将成员序列化为 SOAP 正文中的元素
/// </summary>
[MessageBodyMember]
public Stream FileData;
}
/// <summary>
/// IStreamed接口
/// </summary>
[ServiceContract]
public interface IStreamed
{
/// <summary>
/// 上传文件
/// </summary>
/// <remarks>
/// 1、支持数据流传输的绑定有:BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding
/// 2、流数据类型必须是可序列化的 Stream 或 MemoryStream
// /3、传递时消息体(Message Body)中不能包含其他数据,即参数中只能有一个System.ServiceModel.MessageBodyMember
/// </remarks>
/// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>
[OperationContract]
void UploadFile(FileWrapper fileWrapper);
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.IO;
namespace WCF.ServiceLib.Message
{
/// <summary>
/// 消息契约(定义与 SOAP 消息相对应的强类型类)
/// </summary>
[MessageContract]
public class FileWrapper
{
/// <summary>
/// 指定数据成员为 SOAP 消息头
/// </summary>
[MessageHeader]
public string FilePath;
/// <summary>
/// 指定将成员序列化为 SOAP 正文中的元素
/// </summary>
[MessageBodyMember]
public Stream FileData;
}
/// <summary>
/// IStreamed接口
/// </summary>
[ServiceContract]
public interface IStreamed
{
/// <summary>
/// 上传文件
/// </summary>
/// <remarks>
/// 1、支持数据流传输的绑定有:BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding
/// 2、流数据类型必须是可序列化的 Stream 或 MemoryStream
// /3、传递时消息体(Message Body)中不能包含其他数据,即参数中只能有一个System.ServiceModel.MessageBodyMember
/// </remarks>
/// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>
[OperationContract]
void UploadFile(FileWrapper fileWrapper);
}
}
Streamed.cs
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.IO;
namespace WCF.ServiceLib.Message
{
/// <summary>
/// IStreamed类
/// </summary>
public class Streamed : IStreamed
{
/// <summary>
/// 上传文件
/// </summary>
/// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>
public void UploadFile(FileWrapper fileWrapper)
{
var sourceStream = fileWrapper.FileData;
var targetStream = new FileStream(fileWrapper.FilePath,
FileMode.Create,
FileAccess.Write,
FileShare.None);
var buffer = new byte[4096];
var count = 0;
while ((count = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
{
targetStream.Write(buffer, 0, count);
}
targetStream.Close();
sourceStream.Close();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.IO;
namespace WCF.ServiceLib.Message
{
/// <summary>
/// IStreamed类
/// </summary>
public class Streamed : IStreamed
{
/// <summary>
/// 上传文件
/// </summary>
/// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>
public void UploadFile(FileWrapper fileWrapper)
{
var sourceStream = fileWrapper.FileData;
var targetStream = new FileStream(fileWrapper.FilePath,
FileMode.Create,
FileAccess.Write,
FileShare.None);
var buffer = new byte[4096];
var count = 0;
while ((count = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
{
targetStream.Write(buffer, 0, count);
}
targetStream.Close();
sourceStream.Close();
}
}
}
2、宿主
Streamed.cs
using
(ServiceHost host
=
new
ServiceHost(
typeof
(WCF.ServiceLib.Message.Streamed)))
{
host.Open();
Console.WriteLine("服务已启动(WCF.ServiceLib.Message.Streamed)");
Console.WriteLine("按<ENTER>停止服务");
Console.ReadLine();
}
{
host.Open();
Console.WriteLine("服务已启动(WCF.ServiceLib.Message.Streamed)");
Console.WriteLine("按<ENTER>停止服务");
Console.ReadLine();
}
App.config
<?
xml version="1.0" encoding="utf-8"
?>
< configuration >
< system.serviceModel >
< services >
<!-- name - 提供服务的类名 -->
<!-- behaviorConfiguration - 指定相关的行为配置 -->
< service name ="WCF.ServiceLib.Message.Streamed" behaviorConfiguration ="MessageBehavior" >
<!-- address - 服务地址 -->
<!-- binding - 通信方式 -->
<!-- contract - 服务契约 -->
<!-- bindingConfiguration - 指定相关的绑定配置 -->
< endpoint address ="Message/Streamed" binding ="netTcpBinding" contract ="WCF.ServiceLib.Message.IStreamed" bindingConfiguration ="StreamedBindingConfiguration" />
< endpoint address ="mex" binding ="mexHttpBinding" contract ="IMetadataExchange" />
< host >
< baseAddresses >
< add baseAddress ="http://localhost:12345/Message/Streamed/" />
< add baseAddress ="net.tcp://localhost:54321/" />
</ baseAddresses >
</ host >
</ service >
</ services >
< behaviors >
< serviceBehaviors >
< behavior name ="MessageBehavior" >
<!-- httpGetEnabled - 使用get方式提供服务 -->
< serviceMetadata httpGetEnabled ="true" />
< serviceDebug includeExceptionDetailInFaults ="true" />
</ behavior >
</ serviceBehaviors >
</ behaviors >
< bindings >
< netTcpBinding >
<!-- transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息 -->
<!-- maxReceivedMessageSize - 在采用此绑定配置的通道上可接收的最大消息大小(单位:字节) -->
<!-- receiveTimeout - 在传输引发异常之前可用于完成读取操作的时间间隔 -->
< binding name ="StreamedBindingConfiguration" transferMode ="Streamed" maxReceivedMessageSize ="1073741824" receiveTimeout ="00:10:00" />
</ netTcpBinding >
</ bindings >
</ system.serviceModel >
</ configuration >
< configuration >
< system.serviceModel >
< services >
<!-- name - 提供服务的类名 -->
<!-- behaviorConfiguration - 指定相关的行为配置 -->
< service name ="WCF.ServiceLib.Message.Streamed" behaviorConfiguration ="MessageBehavior" >
<!-- address - 服务地址 -->
<!-- binding - 通信方式 -->
<!-- contract - 服务契约 -->
<!-- bindingConfiguration - 指定相关的绑定配置 -->
< endpoint address ="Message/Streamed" binding ="netTcpBinding" contract ="WCF.ServiceLib.Message.IStreamed" bindingConfiguration ="StreamedBindingConfiguration" />
< endpoint address ="mex" binding ="mexHttpBinding" contract ="IMetadataExchange" />
< host >
< baseAddresses >
< add baseAddress ="http://localhost:12345/Message/Streamed/" />
< add baseAddress ="net.tcp://localhost:54321/" />
</ baseAddresses >
</ host >
</ service >
</ services >
< behaviors >
< serviceBehaviors >
< behavior name ="MessageBehavior" >
<!-- httpGetEnabled - 使用get方式提供服务 -->
< serviceMetadata httpGetEnabled ="true" />
< serviceDebug includeExceptionDetailInFaults ="true" />
</ behavior >
</ serviceBehaviors >
</ behaviors >
< bindings >
< netTcpBinding >
<!-- transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息 -->
<!-- maxReceivedMessageSize - 在采用此绑定配置的通道上可接收的最大消息大小(单位:字节) -->
<!-- receiveTimeout - 在传输引发异常之前可用于完成读取操作的时间间隔 -->
< binding name ="StreamedBindingConfiguration" transferMode ="Streamed" maxReceivedMessageSize ="1073741824" receiveTimeout ="00:10:00" />
</ netTcpBinding >
</ bindings >
</ system.serviceModel >
</ configuration >
3、客户端
Streamed.cs
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
using System.IO;
namespace Client2.Message
{
/// <summary>
/// 演示Message.Streamed的类
/// </summary>
public class Streamed
{
/// <summary>
/// 流数据上传文件
/// </summary>
/// <param name="source">源文件地址</param>
/// <param name="destination">目标路径</param>
public void HelloStreamed(string source, string destination)
{
try
{
var proxy = new MessageSvc.Streamed.StreamedClient();
var sr = new System.IO.FileStream(
source, System.IO.FileMode.Open);
proxy.UploadFile(destination + Path.GetFileName(source), sr);
sr.Close();
proxy.Close();
MessageBox.Show("上传成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
using System.IO;
namespace Client2.Message
{
/// <summary>
/// 演示Message.Streamed的类
/// </summary>
public class Streamed
{
/// <summary>
/// 流数据上传文件
/// </summary>
/// <param name="source">源文件地址</param>
/// <param name="destination">目标路径</param>
public void HelloStreamed(string source, string destination)
{
try
{
var proxy = new MessageSvc.Streamed.StreamedClient();
var sr = new System.IO.FileStream(
source, System.IO.FileMode.Open);
proxy.UploadFile(destination + Path.GetFileName(source), sr);
sr.Close();
proxy.Close();
MessageBox.Show("上传成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
App.config
<?
xml version="1.0" encoding="utf-8"
?>
< configuration >
< system.serviceModel >
< client >
<!-- address - 服务地址 -->
<!-- binding - 通信方式 -->
<!-- contract - 服务契约 -->
< endpoint address ="net.tcp://localhost:54321/Message/Streamed" binding ="netTcpBinding" contract ="MessageSvc.Streamed.IStreamed" bindingConfiguration ="StreamedBindingConfiguration" />
</ client >
< bindings >
< netTcpBinding >
<!-- transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息 -->
<!-- sendTimeout - 在传输引发异常之前可用于完成写入操作的时间间隔 -->
< binding name ="StreamedBindingConfiguration" transferMode ="Streamed" sendTimeout ="00:10:00" />
</ netTcpBinding >
</ bindings >
</ system.serviceModel >
</ configuration >
< configuration >
< system.serviceModel >
< client >
<!-- address - 服务地址 -->
<!-- binding - 通信方式 -->
<!-- contract - 服务契约 -->
< endpoint address ="net.tcp://localhost:54321/Message/Streamed" binding ="netTcpBinding" contract ="MessageSvc.Streamed.IStreamed" bindingConfiguration ="StreamedBindingConfiguration" />
</ client >
< bindings >
< netTcpBinding >
<!-- transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息 -->
<!-- sendTimeout - 在传输引发异常之前可用于完成写入操作的时间间隔 -->
< binding name ="StreamedBindingConfiguration" transferMode ="Streamed" sendTimeout ="00:10:00" />
</ netTcpBinding >
</ bindings >
</ system.serviceModel >
</ configuration >
运行结果:
上传文件后提示上传成功
OK
[源码下载]