WCF传输大数据 --断点续传(upload、download)
using System;
using System.IO;
using System.Runtime.Serialization;
using System.ServiceModel; namespace WcfServer
{
internal class Program
{
private static void Main()
{
using (var host = new ServiceHost(typeof (StreamServices)))
{
host.Opened += (a, b) => Console.WriteLine("...");
host.Open(); Console.ReadKey();
}
}
} [ServiceContract(Name = "IStreamServices",
SessionMode = SessionMode.Required,
Namespace = "http://www.msdn.com/IStreamServices/14/04/11")]
public interface IStreamServices
{
[OperationContract(Name = "Upload")]
FileInformation Upload(FileInformation fileInfo); [OperationContract(Name = "Download")]
FileInformation Download(FileInformation fileInfo);
} [ServiceBehavior(Name = "StreamServices",
Namespace = "http://www.msdn.com/StreamServices/14/04/11"
, InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class StreamServices : IStreamServices
{
private static readonly string AttachmentPath = AppDomain.CurrentDomain.BaseDirectory + "Attachments//"; #region IServices 成员 public FileInformation Upload(FileInformation fileInfo)
{
try
{
if (fileInfo == null)
return new FileInformation {Error = "FileInformation对象不能为空"};
if (string.IsNullOrEmpty(fileInfo.FileNameNew))
fileInfo.FileNameNew = Guid.NewGuid() + fileInfo.FileSuffix;
var savePath = AttachmentPath + fileInfo.FileNameNew;
using (var fs = new FileStream(savePath, FileMode.OpenOrCreate))
{
long offset = fileInfo.Offset;
using (var write = new BinaryWriter(fs))
{
write.Seek((int) offset, SeekOrigin.Begin);
write.Write(fileInfo.Data);
fileInfo.Offset = fs.Length;
}
}
return fileInfo;
}
catch (IOException ex)
{
return new FileInformation {Error = ex.Message};
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return new FileInformation {Error = "wcf内部错误"};
}
} public FileInformation Download(FileInformation fileInfo)
{
try
{
if (fileInfo == null)
return new FileInformation {Error = "FileInformation对象不能为空"};
var readFileName = AttachmentPath + fileInfo.FileName;
if (!File.Exists(readFileName))
return new FileInformation {Error = "DirectoryNotFoundException"};
var stream = File.OpenRead(readFileName);
fileInfo.Length = stream.Length;
if (fileInfo.Offset.Equals(fileInfo.Length))
return new FileInformation {Offset = fileInfo.Offset, Length = stream.Length};
var maxSize = fileInfo.MaxSize > * ? * : fileInfo.MaxSize;
fileInfo.Data =
new byte[fileInfo.Length - fileInfo.Offset <= maxSize ? fileInfo.Length - fileInfo.Offset : maxSize];
stream.Position = fileInfo.Offset;
stream.Read(fileInfo.Data, , fileInfo.Data.Length);
return fileInfo;
}
catch (IOException ex)
{
return new FileInformation {Error = ex.Message};
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return new FileInformation {Error = "wcf内部错误"};
}
} #endregion
} [DataContract(Name = "MyStreamInfo")]
public class FileInformation
{
[DataMember(Name = "Length", IsRequired = true)]
public long Length { get; set; } [DataMember(Name = "FileName", IsRequired = true)]
public string FileName { get; set; } [DataMember(Name = "Data")]
public byte[] Data { get; set; } [DataMember(Name = "FileSuffix")]
public string FileSuffix { get; set; } [DataMember(Name = "Offset", IsRequired = true)]
public long Offset { get; set; } [DataMember(Name = "Error")]
public string Error { get; set; } private int maxSize = *; //200k [DataMember(Name = "MaxSize")]
public int MaxSize
{
get { return maxSize; }
set { maxSize = value; }
} [DataMember(Name = "KeyToken")]
public string KeyToken { get; set; } [DataMember(Name = "FileNameNew")]
public string FileNameNew { get; set; }
}
}
using System;
using System.IO;
using WcfClientApp.ServiceReference1; namespace WcfClientApp
{
internal class Program
{
private static void Main()
{
Upload();
Download();
Console.ReadKey();
} /// <summary>
/// 上传
/// </summary>
private static void Upload()
{
try
{
var filePath = AppDomain.CurrentDomain.BaseDirectory + "UploadFiles//张国荣 - 共同度过.mp3";
const string fileName = "张国荣 - 共同度过.mp3";
const int maxSize = *;
if (!File.Exists(filePath))
{
Console.WriteLine("DirectoryNotFoundException");
return;
}
FileStream stream = File.OpenRead(filePath);
var fileInfo = new MyStreamInfo {Length = stream.Length, FileName = fileName,FileSuffix=".mp3"};
using (var client = new StreamServicesClient())
{
while (fileInfo.Length != fileInfo.Offset)
{
fileInfo.Data =
new byte[
fileInfo.Length - fileInfo.Offset <= maxSize
? fileInfo.Length - fileInfo.Offset
: maxSize];
stream.Position = fileInfo.Offset;
stream.Read(fileInfo.Data, , fileInfo.Data.Length);
fileInfo = client.Upload(fileInfo);
if (!string.IsNullOrEmpty(fileInfo.Error))
{
Console.WriteLine(fileInfo.Error);
break;
}
}
if (fileInfo.Length.Equals(fileInfo.Offset))
Console.WriteLine("Upload successful!");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// 下载
/// </summary>
private static void Download()
{
try
{
var filePath = AppDomain.CurrentDomain.BaseDirectory +
"DownloadFiles//c228d4df-8bdc-468b-96ec-46860c2f026a.mp3";
const string fileName = "c228d4df-8bdc-468b-96ec-46860c2f026a.mp3";
var fileInfo = new MyStreamInfo {FileName = fileName, Length = , MaxSize = *};
using (var client = new StreamServicesClient())
{
while (fileInfo.Length != fileInfo.Offset)
{
fileInfo = client.Download(fileInfo);
if (!string.IsNullOrEmpty(fileInfo.Error))
{
Console.WriteLine(fileInfo.Error);
break;
}
using (var fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
long offset = fileInfo.Offset;
using (var write = new BinaryWriter(fs))
{
write.Seek((int) offset, SeekOrigin.Begin);
write.Write(fileInfo.Data);
fileInfo.Offset = fs.Length;
}
}
}
if (fileInfo.Length.Equals(fileInfo.Offset))
Console.WriteLine("download successful!");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
使用MaxSize控制下载、上传大小(k)
一开始设计的时候,我考虑使用双工模式,但是觉得有不太好,使用双工模式反而增加了代码开发量。
不知道各位有没有什么更好的解决办法?是否愿意分享一下,谢谢各位的指点。
WCF传输大数据 --断点续传(upload、download)的更多相关文章
- WCF传输大数据的设置
在从客户端向WCF服务端传送较大数据(>65535B)的时候,发现程序直接从Reference的BeginInvoke跳到EndInvoke,没有进入服务端的Service实际逻辑中,怀疑是由于 ...
- 【转】WCF传输大数据的设置
在从客户端向WCF服务端传送较大数据(>65535B)的时候,发现程序直接从Reference的BeginInvoke跳到EndInvoke,没有进入服务端的Service实际逻辑中,怀疑是由于 ...
- WCF传输大数据的设置2
本节主要内容:1.如何读取Binding中的binding元素.2.CustomBinding元素的基本配置.3.代码示例 一.Bingding是由binding元素构成的,可以根据实际需要,进行适当 ...
- 快速传输大数据(tar+lz4+pv)
快速传输大数据(tar+lz4+pv) 如果用传统SCP远程拷贝,速度是比较慢的.现在采用lz4压缩传输.LZ4是一个非常快的无损压缩算法,压缩速度在单核300MB/S,可扩展支持多核CPU.它还 ...
- 解决WCF传输的数据量过大问题
今天写了个WCF接口,然后自测通过,和别人联调时报 远程服务器返回错误: (413) Request Entity Too Large 错误!记得以前写的时候也出现过这个错误,大致解决办 ...
- WCF传送大数据时的错误“ 超出最大字符串内容长度配额”
格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: GetLzdtArticleResult.InnerException 消息是“反序 ...
- php传输大数据大文件时候php.ini相关设置
post_max_size which is directly related to the POST size---针对采用post上传的,大文件,此项为关键 upload_max_filesize ...
- 【转载】大数据量传输时配置WCF的注意事项
WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMessageSize:获取或设置配置了此绑定 ...
- WCF 传输和接受大数据
向wcf传入大数据暂时还没找到什么好方案,大概测了一下传输2M还是可以的,有待以后解决. 接受wcf传回的大数据,要进行web.config的配置,刚开是从网上搜自己写进行配置,折磨了好长时间. 用以 ...
随机推荐
- n个数取前k个最小数
算法题:K 个最近的点 给定一些 points 和一个 origin,从 points 中找到 k 个离 origin 最近的点.按照距离由小到大返回.如果两个点有相同距离,则按照x值来排序:若x值也 ...
- 利用Minhash和LSH寻找相似的集合(转)
问题背景 给出N个集合,找到相似的集合对,如何实现呢?直观的方法是比较任意两个集合.那么可以十分精确的找到每一对相似的集合,但是时间复杂度是O(n2).当N比较小时,比如K级,此算法可以在接受的时间范 ...
- mong大牛的blog
MongoDB权威指南(3)-查询1.find方法介绍在不传入参数的情况下,find方法缺省使用 http://www.educity.cn/wenda/389594.html 这个归纳的比较好:可 ...
- 6-9 😢 5小时的debug: 从rails 命令运行超慢开始->删除rails->删除ruby->删除rvm->安装上rvm->安装上ruby
上午,莫名其妙的rails app不能用了,rails -v一查发现不存在.ruby -v发现是2.0的版本.很着急上火,因为很少使用过rvm这个ruby版本控制器.所以照官网文档.从新安装ruby, ...
- TTL的具体含义
TTL(Time To Live)生存时间值,在IP数据包从源到目的的整个转发路径上,每经过一个路由器,路由器都会修改这个TTL字段值,具体的做法是把该TTL的值减1,然后再将IP包转发出去.如果在I ...
- Tornado源码分析 --- Cookie和XSRF机制
Cookie和Session的理解: 具体Cookie的介绍,可以参考:HTTP Cookie详解 可以先查看之前的一篇文章:Tornado的Cookie过期问题 XSRF跨域请求伪造(Cross-S ...
- css中的f弹性盒子模型的应用案例
案例1: <!doctype html> <html> <head> <meta charset="utf-8"> <meta ...
- 快速切题 poj 2996 Help Me with the Game 棋盘 模拟 暴力 难度:0
Help Me with the Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3510 Accepted: ...
- 在pixi中使用你的自定义着色器
通过几天的学习,对openGL.shader有了一个大致的了解. 回到学习的初衷吧,在基于pixi.js重构D3项目的时候,因为精灵层级的问题,我得按照一定的先后顺序将不同类别的精灵添加到场景中去. ...
- iOS-----使用AddressBook添加联系人
使用AddressBook添加联系人 添加联系人的步骤如下: 1 创建ABAddressBookRef,这就得到了对地址簿的引用. 2 调用ABPersonCreate()函数创建一个空的ABReco ...