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)

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

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

你可能感兴趣的:(download)