WCF传输大数据 --断点续传(upload、download)

  1 using System;
  2 using System.IO;
  3 using System.Runtime.Serialization;
  4 using System.ServiceModel;
  5 
  6 namespace WcfServer
  7 {
  8     internal class Program
  9     {
 10         private static void Main()
 11         {
 12             using (var host = new ServiceHost(typeof (StreamServices)))
 13             {
 14                 host.Opened += (a, b) => Console.WriteLine("...");
 15                 host.Open();
 16 
 17                 Console.ReadKey();
 18             }
 19         }
 20     }
 21 
 22     [ServiceContract(Name = "IStreamServices",
 23         SessionMode = SessionMode.Required,
 24         Namespace = "http://www.msdn.com/IStreamServices/14/04/11")]
 25     public interface IStreamServices
 26     {
 27         [OperationContract(Name = "Upload")]
 28         FileInformation Upload(FileInformation fileInfo);
 29 
 30         [OperationContract(Name = "Download")]
 31         FileInformation Download(FileInformation fileInfo);
 32     }
 33 
 34     [ServiceBehavior(Name = "StreamServices",
 35         Namespace = "http://www.msdn.com/StreamServices/14/04/11"
 36         , InstanceContextMode = InstanceContextMode.PerCall,
 37         ConcurrencyMode = ConcurrencyMode.Multiple)]
 38     public class StreamServices : IStreamServices
 39     {
 40         private static readonly string AttachmentPath = AppDomain.CurrentDomain.BaseDirectory + "Attachments//";
 41 
 42         #region IServices 成员
 43 
 44         public FileInformation Upload(FileInformation fileInfo)
 45         {
 46             try
 47             {
 48                 if (fileInfo == null)
 49                     return new FileInformation {Error = "FileInformation对象不能为空"};
 50                 if (string.IsNullOrEmpty(fileInfo.FileNameNew))
 51                     fileInfo.FileNameNew = Guid.NewGuid() + fileInfo.FileSuffix;
 52                 var savePath = AttachmentPath + fileInfo.FileNameNew;
 53                 using (var fs = new FileStream(savePath, FileMode.OpenOrCreate))
 54                 {
 55                     long offset = fileInfo.Offset;
 56                     using (var write = new BinaryWriter(fs))
 57                     {
 58                         write.Seek((int) offset, SeekOrigin.Begin);
 59                         write.Write(fileInfo.Data);
 60                         fileInfo.Offset = fs.Length;
 61                     }
 62                 }
 63                 return fileInfo;
 64             }
 65             catch (IOException ex)
 66             {
 67                 return new FileInformation {Error = ex.Message};
 68             }
 69             catch (Exception ex)
 70             {
 71                 System.Diagnostics.Debug.WriteLine(ex.Message);
 72                 return new FileInformation {Error = "wcf内部错误"};
 73             }
 74         }
 75 
 76         public FileInformation Download(FileInformation fileInfo)
 77         {
 78             try
 79             {
 80                 if (fileInfo == null)
 81                     return new FileInformation {Error = "FileInformation对象不能为空"};
 82                 var readFileName = AttachmentPath + fileInfo.FileName;
 83                 if (!File.Exists(readFileName))
 84                     return new FileInformation {Error = "DirectoryNotFoundException"};
 85                 var stream = File.OpenRead(readFileName);
 86                 fileInfo.Length = stream.Length;
 87                 if (fileInfo.Offset.Equals(fileInfo.Length))
 88                     return new FileInformation {Offset = fileInfo.Offset, Length = stream.Length};
 89                 var maxSize = fileInfo.MaxSize > 1024*500 ? 1024*300 : fileInfo.MaxSize;
 90                 fileInfo.Data =
 91                     new byte[fileInfo.Length - fileInfo.Offset <= maxSize ? fileInfo.Length - fileInfo.Offset : maxSize];
 92                 stream.Position = fileInfo.Offset;
 93                 stream.Read(fileInfo.Data, 0, fileInfo.Data.Length);
 94                 return fileInfo;
 95             }
 96             catch (IOException ex)
 97             {
 98                 return new FileInformation {Error = ex.Message};
 99             }
100             catch (Exception ex)
101             {
102                 System.Diagnostics.Debug.WriteLine(ex.Message);
103                 return new FileInformation {Error = "wcf内部错误"};
104             }
105         }
106 
107         #endregion
108     }
109 
110     [DataContract(Name = "MyStreamInfo")]
111     public class FileInformation
112     {
113         [DataMember(Name = "Length", IsRequired = true)]
114         public long Length { get; set; }
115 
116         [DataMember(Name = "FileName", IsRequired = true)]
117         public string FileName { get; set; }
118 
119         [DataMember(Name = "Data")]
120         public byte[] Data { get; set; }
121 
122         [DataMember(Name = "FileSuffix")]
123         public string FileSuffix { get; set; }
124 
125         [DataMember(Name = "Offset", IsRequired = true)]
126         public long Offset { get; set; }
127 
128         [DataMember(Name = "Error")]
129         public string Error { get; set; }
130 
131         private int maxSize = 1024*200; //200k
132 
133         [DataMember(Name = "MaxSize")]
134         public int MaxSize
135         {
136             get { return maxSize; }
137             set { maxSize = value; }
138         }
139 
140         [DataMember(Name = "KeyToken")]
141         public string KeyToken { get; set; }
142 
143         [DataMember(Name = "FileNameNew")]
144         public string FileNameNew { get; set; }
145     }
146 }
View Code
  1 using System;
  2 using System.IO;
  3 using WcfClientApp.ServiceReference1;
  4 
  5 namespace WcfClientApp
  6 {
  7     internal class Program
  8     {
  9         private static void Main()
 10         {
 11             Upload();
 12             Download();
 13             Console.ReadKey();
 14         }
 15 
 16         /// <summary>
 17         /// 上传
 18         /// </summary>
 19         private static void Upload()
 20         {
 21             try
 22             {
 23                 var filePath = AppDomain.CurrentDomain.BaseDirectory + "UploadFiles//张国荣 - 共同度过.mp3";
 24                 const string fileName = "张国荣 - 共同度过.mp3";
 25                 const int maxSize = 1024*200;
 26                 if (!File.Exists(filePath))
 27                 {
 28                     Console.WriteLine("DirectoryNotFoundException");
 29                     return;
 30                 }
 31                 FileStream stream = File.OpenRead(filePath);
 32                 var fileInfo = new MyStreamInfo {Length = stream.Length, FileName = fileName,FileSuffix=".mp3"};
 33                 using (var client = new StreamServicesClient())
 34                 {
 35                     while (fileInfo.Length != fileInfo.Offset)
 36                     {
 37                         fileInfo.Data =
 38                             new byte[
 39                                 fileInfo.Length - fileInfo.Offset <= maxSize
 40                                     ? fileInfo.Length - fileInfo.Offset
 41                                     : maxSize];
 42                         stream.Position = fileInfo.Offset;
 43                         stream.Read(fileInfo.Data, 0, fileInfo.Data.Length);
 44                         fileInfo = client.Upload(fileInfo);
 45                         if (!string.IsNullOrEmpty(fileInfo.Error))
 46                         {
 47                             Console.WriteLine(fileInfo.Error);
 48                             break;
 49                         }
 50                     }
 51                     if (fileInfo.Length.Equals(fileInfo.Offset))
 52                         Console.WriteLine("Upload successful!");
 53                 }
 54             }
 55             catch (Exception ex)
 56             {
 57                 Console.WriteLine(ex.Message);
 58             }
 59         }
 60         /// <summary>
 61         /// 下载
 62         /// </summary>
 63         private static void Download()
 64         {
 65             try
 66             {
 67                 var filePath = AppDomain.CurrentDomain.BaseDirectory +
 68                                "DownloadFiles//c228d4df-8bdc-468b-96ec-46860c2f026a.mp3";
 69                 const string fileName = "c228d4df-8bdc-468b-96ec-46860c2f026a.mp3";
 70                 var fileInfo = new MyStreamInfo {FileName = fileName, Length = 1, MaxSize = 1024*200};
 71                 using (var client = new StreamServicesClient())
 72                 {
 73                     while (fileInfo.Length != fileInfo.Offset)
 74                     {
 75                         fileInfo = client.Download(fileInfo);
 76                         if (!string.IsNullOrEmpty(fileInfo.Error))
 77                         {
 78                             Console.WriteLine(fileInfo.Error);
 79                             break;
 80                         }
 81                         using (var fs = new FileStream(filePath, FileMode.OpenOrCreate))
 82                         {
 83                             long offset = fileInfo.Offset;
 84                             using (var write = new BinaryWriter(fs))
 85                             {
 86                                 write.Seek((int) offset, SeekOrigin.Begin);
 87                                 write.Write(fileInfo.Data);
 88                                 fileInfo.Offset = fs.Length;
 89                             }
 90                         }
 91                     }
 92                     if (fileInfo.Length.Equals(fileInfo.Offset))
 93                         Console.WriteLine("download successful!");
 94                 }
 95             }
 96             catch (Exception ex)
 97             {
 98                 Console.WriteLine(ex.Message);
 99             }
100         }
101     }
102 }
View Code

使用MaxSize控制下载、上传大小(k)

一开始设计的时候,我考虑使用双工模式,但是觉得有不太好,使用双工模式反而增加了代码开发量。

不知道各位有没有什么更好的解决办法?是否愿意分享一下,谢谢各位的指点。

posted on 2014-04-11 13:53  SonyXbox  阅读(3248)  评论(2编辑  收藏  举报

导航