WCF教程--使用流Stream进行文件的上传下载

wpf项目中,区分客户端和服务端,需要2端进行数据同步和文件传输。

wcf 文件上传的例子网上很多,我也是借鉴别人的示例。wcf 文件下载的示例网上就很少了,不知道是不是因为两者的处理方式比较类似,别人就没有再上传了。 

WCF 支持传送二进制流数据,但有一定的限制。

只有 BasicHttpBinding、WebHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 支持传送流数据。

流数据类型必须是可序列化的 Stream 或 MemoryStream。

传递时消息体(Message Body)中不能包含其他数据。

参考:http://www.csharpwin.com/csharpspace/10780r501.shtml 

1 定义接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
IUploadFile.cs
[ServiceContract]
     public  interface  IUploadFile
     {
         /// <summary>
         /// 上传文件
         /// </summary>
         [OperationContract(Action =  "UploadFile" , IsOneWay =  true )]
         void  UploadFileMethod(FileUploadMessage myFileMessage);
         /// <summary>
         /// 获取文件列表
         /// </summary>
         [OperationContract]
         string [] GetFilesList();
         /// <summary>
         /// 下载文件
         /// </summary>
         [OperationContract]
         Stream DownLoadFile( string  fileName);
     }
     [MessageContract]
     public  class  FileUploadMessage
     {
         [MessageHeader(MustUnderstand =  true )]
         public  string  FileName;
         [MessageBodyMember(Order = 1)]
         public  Stream FileData;
     }

2.实现接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
UploadFile.svc.cs
public  class  UploadFile : IUploadFile
     {
         /// <summary>
         /// 服务器地图文件保存路径
         /// </summary>
         private  string  savePath =  @"D:\矿车定位上传地图备份" ;
         /// <summary>
         /// 上传文件
         /// </summary>
         public  void  UploadFileMethod(FileUploadMessage myFileMessage)
         {
             if (!Directory.Exists(savePath)) //地图存放的默认文件夹是否存在
             {
                 Directory.CreateDirectory(savePath); //不存在则创建
             }
             string  fileName = myFileMessage.FileName; //文件名
             string  fileFullPath = Path.Combine(savePath, fileName); //合并路径生成文件存放路径
             Stream sourceStream = myFileMessage.FileData;
             if  (sourceStream ==  null ) {  return ; }
             if  (!sourceStream.CanRead) {  return ; }
             //创建文件流,读取流中的数据生成文件
             using  (FileStream fs =  new  FileStream(fileFullPath, FileMode.Create, FileAccess.Write, FileShare.None))
             {
                 try
                 {
                     const  int  bufferLength = 4096;
                     byte [] myBuffer =  new  byte [bufferLength]; //数据缓冲区
                     int  count;
                     while  ((count = sourceStream.Read(myBuffer, 0, bufferLength)) > 0)
                     {
                         fs.Write(myBuffer, 0, count);
                     }
                     fs.Close();
                     sourceStream.Close();
                 }
                 catch  return ; }
             }
         }
         /// <summary>
         /// 获取文件列表
         /// </summary>
         public  string [] GetFilesList()
         {
             if (!Directory.Exists(savePath)) //判断文件夹路径是否存在
             {
                 return  null ;
             }
             DirectoryInfo myDirInfo =  new  DirectoryInfo(savePath);
             FileInfo[] myFileInfoArray = myDirInfo.GetFiles( "*.zip" );
             string [] myFileList =  new  string [myFileInfoArray.Length];
             //文件排序
             for  ( int  i = 0; i < myFileInfoArray.Length - 1;i++ )
             {
                 for  ( int  j = i + 1; j < myFileInfoArray.Length; j++)
                 {
                     if (myFileInfoArray[i].LastWriteTime > myFileInfoArray[j].LastWriteTime)
                     {
                         FileInfo myTempFileInfo = myFileInfoArray[i];
                         myFileInfoArray[i] = myFileInfoArray[j];
                         myFileInfoArray[j] = myTempFileInfo;
                     }
                 }
             }
             for  ( int  i = 0; i < myFileInfoArray.Length; i++)
             {
                 myFileList[i] = myFileInfoArray[i].Name;
             }
             return  myFileList;
         }
         /// <summary>
         /// 下载地图
         /// </summary>
         public  Stream DownLoadFile( string  fileName)
         {
             string  fileFullPath = Path.Combine(savePath, fileName); //服务器文件路径
             if (!File.Exists(fileFullPath)) //判断文件是否存在
             {
                 return  null ;
             }
             try
             {
                 Stream myStream = File.OpenRead(fileFullPath);
                 return  myStream;
             }
             catch  return  null ; }
         }
     }

3.配置上传文件大小限制:

4.客户端上传文件方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
客户端上传文件方法
/// <summary>
         /// 上传文件
         /// </summary>
         public  void  UploadFileMethod( string  fileName, string  fileFullPath)
         {
             UploadFile_WcfService.FileUploadMessage myFileMessage =  new  DataProcess.UploadFile_WcfService.FileUploadMessage();
             myFileMessage.FileName = fileName; //文件名
             using  (FileStream fs = File.OpenRead(fileFullPath))
             {
                 myFileMessage.FileData = fs;
                 UploadFile_WcfService.IUploadFile myService = myClient.ChannelFactory.CreateChannel();
                 try
                 {
                     myService.UploadFileMethod(myFileMessage);
                 }
                 catch  { }
                 //关闭流
                 fs.Close();
             }
         }

客户端下载方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
客户端下载文件方法
isExit =  false ; //该变量是窗体是否关闭的标志,如果窗体关闭置为true,跳出写文件循环
//下载地图文件保存路径
             string  saveFilePath = saveFilePathObj.ToString();
             //从服务器中获取地图文件流
             Stream sourceStream = myUploadFileClass.DownloadFile(fileNameChecked);
             if  (sourceStream !=  null )
             {
                 if  (sourceStream.CanRead)
                 {
                     using  (FileStream fs =  new  FileStream(saveFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
                     {
                         const  int  bufferLength = 4096;
                         byte [] myBuffer =  new  byte [bufferLength];
                         int  count;
                         while  ((count = sourceStream.Read(myBuffer, 0, bufferLength)) > 0)
                         {
                             if  (isExit ==  false )
                             {
                                 fs.Write(myBuffer, 0, count);
                             }
                             else //窗体已经关闭跳出循环
                             {
                                 break ;
                             }
                         }
                         fs.Close();
                         sourceStream.Close();
                     }
                 }
             }

上面的配置上传一些比较大的文件应该是没有问题了,如果需要下载大文件还需要在客户端的app.config 中设置如下配置,此处的重点是设置transferMode="Streamed"默认是Buffered
,如果是Buffered是无法设置较大的maxReceivedMessageSize="9223372036854775807"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  < behaviors >
       < serviceBehaviors >
         < behavior  name = "DefaultBehavior" >
           < serviceDe <a  href = "http://www.suchso.com/programmer/chengxuyuan-duanzi-bug-shangwang.html"  class = "keylink"  title = " Bug修复"  target = "_blank" >bug</ a > includeExceptionDetailInFaults="true" />
           < serviceMetadata  httpGetEnabled = "true"   httpGetUrl = "http://192.168.20.94:8091/SyncDataService/mex" />
         </ behavior >
       </ serviceBehaviors >
     </ behaviors >
     < bindings >
       < netTcpBinding >
         < binding  name = "TcpBindingConfig"  maxBufferPoolSize = "524288000"  maxBufferSize = "65536000"  maxReceivedMessageSize = "65536000"  transferMode = "Streamed" >
           < security  mode = "None"  />
         </ binding >
       </ netTcpBinding >
       < basicHttpBinding >
         < binding  name = "BasicHttpBindingConfig"  maxBufferPoolSize = "524288000"  maxBufferSize = "65536000"  maxReceivedMessageSize = "65536000"  sendTimeout = "00:02:00"  transferMode = "Streamed" >
           < security  mode = "None" />
         </ binding >
       </ basicHttpBinding >
     </ bindings >


原文链接:点击打开链接

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值