通过传递Stream对象来传递大数据文件,但是有一些限制:
1、只有 BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 支持传送流数据。
2、 流数据类型必须是可序列化的 Stream 或 MemoryStream。
3、 传递时消息体(Message Body)中不能包含其他数据。
4、TransferMode的限制和MaxReceivedMessageSize的限制等。
下面具体实现:新建一个FileService,接口文件的代码如下:
using System.IO; using System.ServiceModel; namespace FileService { [ServiceContract] public interface IFileService { [OperationContract] void UpLoadFile(FileUploadMessage fileUploadMessage); } [MessageContract] public class FileUploadMessage { [MessageHeader] public string FileName { get; set; } [MessageBodyMember] public Stream FileData { get; set; } } }
定义FileUploadMessage类的目的是因为第三个限制,要不然文件名及其他信息就没办法传递给WCF了,根据第二个限制,文件数据是用System.IO.Stream来传递的。下面是接口的具体实现。
using System; using System.IO; namespace FileService { public class FileService : IFileService { //保存文件的目录路径 private const string SaveDirectory = @"F:\V2.4ShareFolder\PRO"; public void UpLoadFile(FileUploadMessage fileUploadMessage) { string fileName = fileUploadMessage.FileName; Stream sourceStream = fileUploadMessage.FileData; FileStream targetStream = null; if (!sourceStream.CanRead) { throw new Exception("数据流不可读!"); } string filePath = Path.Combine(SaveDirectory, fileName); using (targetStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) { //read from the input stream in 4K chunks //and save to output stream const int bufferLen = 4096; var buffer = new byte[bufferLen]; try { int count; while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0) { targetStream.Write(buffer, 0, count); } } finally { sourceStream.Close(); } } } } }
实现的功能很简单,把文件保存到特定的目录中即可。下面是进行config的配置。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> </appSettings> <system.web> <compilation debug="true" /> </system.web> <!-- When deploying the service library project, the content of the config file must be added to the host's app.config file. System.Configuration does not support config files for libraries. --> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="FileServiceBinding" maxReceivedMessageSize="10485760" transferMode="Streamed"></binding> </basicHttpBinding> </bindings> <services> <service name="FileService.FileService" behaviorConfiguration="FileServiceBehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:9090/FileService"/> </baseAddresses> </host> <endpoint address="" binding="basicHttpBinding" contract="FileService.IFileService" bindingConfiguration="FileServiceBinding"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="FileServiceBehavior"> <!-- To avoid disclosing metadata information, set the values below to false before deployment --> <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/> <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
新建客户端,进行服务的测试。
namespace TestClient { class Program { static void Main(string[] args) { FileServiceClient fileServiceClient = new FileServiceClient(); string filepath = @"F:\V2.4ShareFolder\EPHMDY1031975917464876001-7131898.zip"; using (Stream stream = new FileStream(filepath, FileMode.Open)) { fileServiceClient.UpLoadFile("222.zip", stream); } Console.ReadKey(); } } }