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的配置,刚开是从网上搜自己写进行配置,折磨了好长时间. 用以 ...
随机推荐
- bzoj 2818 gcd 线性欧拉函数
2818: Gcd Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 给定整数N,求1< ...
- codeforces 356 div2 C.Bear and Prime 100 数学
C. Bear and Prime 100 time limit per test 1 second memory limit per test 256 megabytes input standar ...
- Git入门及常用命令(1)(window环境下)
文章参考摘抄自:git教程 1.git的安装 Windows下要使用很多Linux/Unix的工具时,需要Cygwin这样的模拟环境,Git也一样.Cygwin的安装和配置都比较复杂,就不建议你折腾了 ...
- poj1087最大流拆点
刚开始看这题太长了就放着,后来做了之后才发现并不难,就是构造图有点麻烦 一开始写了180行@.@结果tle了,后来想到用map直接访问的话可能会快点,就不用每次循环了 #include<map& ...
- linux下运行jar
方式一: java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二: java -jar XXX.jar ...
- 基于Oracle的SQL优化(崔华著)-整理笔记-第2章“Oracle里的执行计划”
详细介绍了Oracle数据里与执行计划有关的各个方面的内容,包括执行计划的含义,加何查看执行计划,如何得到目标SQL真实的执行计划,如何查看执行计划的执行顺序,Oracle数据库里各种常见的执行计划的 ...
- linux-android-adt
本打算带着唐帅弟弟研究几天手机开发,没想到这老弟天天遇到问题,原来认为他除了错误,没想到啊,我一上手也到处 是错误,折磨我们哥俩了,今天我俩干 了几把扑克,PK了一次羽毛球,回来研究了一会,阿门问题解 ...
- 关于poi操作excel我使用的一些修饰操作
被这情况恶心了.我的excel默认为常规,然后写入数字就成类似number类型,获取值得到的是double类型,2变成2.0.号码变成科学计数法. 做功能找了一段时间,保存下来防止忘记下次浪费时间. ...
- cn_office_Professional_Plus_2010_vol_with_sp2-【x86+x64仅2.45GB】
用官方sp2补丁在cn_office_Professional_Plus_2010_vol基础上集成,无其他任何添加及修改! 文件: cn_office_Professional_Plus_2010_ ...
- 探究js正则匹配方法:match和exec
match是字符串方法,写法为:str.match(reg) exec是正则表达式方法,写法为:reg.exec(str) match和exec在匹配成功时返回的都是数组,在没有匹配上时返回的都是nu ...