2011-06-09 87 views
0

我使用WCF上传到服务器时恢复的文件,我试图恢复我的上传与服务器应用程序下面的代码:使用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)导致第一个字节已经上传。所以我只能附加剩余的字节到部分上传的文件中。通过这种方式,我得到一个缓冲区大小的错误,不能使用寻求,因为方法不支持异常,所以我认为也许这种做法是不正确的。帮帮我!!

我的服务合同:

[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

你使用什么类型的绑定?你可以发布合同接口和示例客户端调用吗? – 2011-06-09 21:25:42

+0

使用所有绑定,nettcp wshttp和basichttp,上传工作正常,但我想恢复上传时死亡导致我使用大文件。 – blur 2011-06-09 21:34:16

回答

0

好像你使用的是标准的SOAP消息,而不是流结合。检查出this link

如果你不想使用WCF的专用于WCF的流api,我会考虑从客户端创建一个'chunking'方法,如果客户端正在上传文件。与FTP可以恢复的方式类似,我会查询服务器以查看当前偏移量,发送一个块或一组块,将它们写入我的持久性(内存,数据库,文件等),然后继续从客户端发送较小的数据块(小心序列化,因为这可能会导致不必要的延迟)。这种技术是你想调查的东西,因为它听起来像客户端'流'到服务器。

顺便说一句,您可能想看看下面的文章,以确定您使用MessageContract是否合适,而不是DataContract。

http://blogs.msdn.com/b/drnick/archive/2007/07/25/data-contract-and-message-contract.aspx

+0

我使用nettcpbinding进行流式传输。正如我所说的,我的困惑是如何将一个剩余部分附加到文件中。目前尚不清楚。 – blur 2011-06-09 22:05:49

0

如果你想恢复功能,你不能做这种方式。您的客户端必须以块形式发送文件,并且必须保留上次成功更新的块的标识。该服务必须处理块并将其附加到存储。

如果最基本的实现,它意味着您的客户端必须将文件分成众所周知的大小的块,并调用每个块的上传操作。该消息还必须包含块ID,并且可能还包含块大小(或标识最后一块的东西)。这也可以与可靠的会话相结合,以允许丢失块的自动重新发送以及为了递送而执行。

也有内部分块的channel implementation的例子。