我正在使用WCF,我正在尝试使用服务器应用程序上的下一代码恢复上传:
class DataUploader : IDataUploader
{
public void Upload(UploadMessage msg)
{
int speed = msg.AvgSpeed * 1024; // convert to KB
Stream stream= msg.DataStream;
string name = msg.VirtualPath;
int seekPoint; // this is get reading the partial uploaded file
using (FileStream fs = new FileStream(@"C:\savedfile.dat, FileMode.Append))
{
int bufferSize = 4 * 1024; // 4KB buffer
byte[] buffer = new byte[bufferSize];
int bytes;
while ((bytes = stream.Read(buffer, startPoint, bufferSize)) > 0)
{
fs.Write(buffer, 0, bytes);
fs.Flush();
}
stream.Close();
fs.Close();
}
}
}
我正在尝试从指定点(startPoint)开始读取流,因为第一个字节已经上传。所以我只能将剩余的字节附加到部分上传的文件中。通过这种方式我得到一个与buffersize的错误,不能使用搜索,因为一个方法不支持异常所以我想也许这种方法是不对的。帮助!
我的服务合同:
[ServiceContract]
interface IDataUploader
{
[OperationContract]
void Upload(UploadMessage msg);
}
我的留言合同:
[MessageContract]
public class UploadMessage
{
[MessageHeader(MustUnderstand = true)]
public string VirtualPath { get; set; }
[MessageHeader(MustUnderstand = true)]
public int AvgSpeed { get; set; }
[MessageBodyMember(Order = 1)]
public Stream DataStream { get; set; }
}
答案 0 :(得分:0)
您似乎正在使用标准的soap消息而不是流式绑定。查看this link
如果您不想使用WCF专有的WCF流媒体API,我会考虑在客户端上传文件时从客户端创建“分块”方法。类似于FTP可以恢复的方式,我会查询服务器以查看当前偏移量,发送一个块或一组块,将它们写入我的持久性(内存,数据库,文件等),然后继续多次调用客户端发送较小的块(注意序列化,因为这会引入不必要的延迟)。这项技术是您想要研究的,因为它听起来像客户端正在“流式传输”到服务器。
顺便说一下,您可能需要查看以下文章,以确定您对MessageContract的使用是否合适,而不是DataContract。
http://blogs.msdn.com/b/drnick/archive/2007/07/25/data-contract-and-message-contract.aspx
答案 1 :(得分:0)
如果你想要恢复功能,你不能这样做。您的客户端必须以块的形式发送文件,并且必须保留上次成功更新的块的ID。该服务必须处理块并将其附加到存储中。
如果最基本的实现意味着您的客户端必须将文件分成众所周知的大小的块并调用每个块的上传操作。该消息还必须包含块ID,也可能包含块大小(或标识最后一个块的内容)。这也可以与可靠的会话结合使用,以允许自动重新发送丢失的块并强制执行订单交付。
还有一个channel implementation的例子,它在内部进行分块。