【问题标题】:WCF and streaming filesWCF 和流文件
【发布时间】:2016-04-07 14:20:33
【问题描述】:

我有一个使用以下方法流式传输文件的 WCF 服务:

public class GetFileService : IGetFileService
{
    public GetFileResponse GetFile(GetFileRequest request)
    {
        var fileStream = new FileStream(request.FileName, FileMode.Open, FileAccess.Read);
        return new GetFileResponse
        {
            StreamResult = fileStream
        };
    }
}

[MessageContract]
public class GetFileResponse
{
    [MessageBodyMember(Order = 1)]
    public Stream StreamResult { get; set; }
}

我的 web.config 有一个带有 transferMode="Streamed" 的 basicHttpBinding,调用服务函数的客户端也是如此

当传输模式设置为流式传输时,这意味着服务在发送之前不会将整个文件缓存在内存中,对吧?但是收到的(调用函数的客户端)呢? 如果我在接收方有如下代码:

GetFileServiceClient getFileService = new GetFileServiceClient();
using ( Stream stream = getFileService.GetFile(@"c:\Temp\pics.zip") )
{
    const int bufferSize = 2048;
    byte[] buffer = new byte[bufferSize];
    using (FileStream outputStream = new FileStream(@"C:\Temp\pics2.zip", FileMode.Create, FileAccess.Write))
    {
        int bytesRead = stream.Read(buffer, 0, bufferSize);
        while (bytesRead > 0)
        {
            outputStream.Write(buffer, 0, bytesRead);
            bytesRead = stream.Read(buffer, 0, bufferSize);
        }
        outputStream.Close();
     }
 }

客户端在调用中没有收到整个文件

 getFileService.GetFile(@"c:\Temp\pics.zip")

或者是否接收到流指针并且仅当在 while 循环中执行对 Read 的调用时才流式传输文件?不知怎的,我觉得这很难消化。我感觉整个文件是通过网络发送的,并且位于 WCF 通信层的某个位置。如果这是真的,我该如何以正确的方式在客户端使用流,以便客户端的内存不会被可能非常大的文件占用。

谢谢

【问题讨论】:

标签: c# wcf filestreams


【解决方案1】:

当传输模式设置为流式传输时,表示服务 在发送之前不会将整个文件缓存在内存中,对吧?

正确

但是收到的(调用函数的客户端)呢?如果 我在接收方有如下代码 客户端在调用中没有收到整个文件

getFileService.GetFile(@"c:\Temp\pics.zip")

在某种程度上,您的网络基础设施正在执行一定数量的数据包缓冲,但在将整个流提供给客户端(或客户端)之前,没有任何东西可以缓冲整个流。传输管理通信,并且可以使用 maxBufferSize、maxBufferPoolSize 和 maxReceivedMessageSize 属性在绑定中进行一定程度的控制

【讨论】:

  • 那么这意味着通信线是打开的,直到最后一个字节被读取,或者直到流被关闭?
  • @JihadHaddad 出于您的目的,是的。事实有点丑陋,因为 WCF 可以缓存连接并使其保持打开状态。您还可以查看启用广泛支持的标准 MTOM。它有一些额外的好处,但是对于从 WCF 流式传输的 Java 客户端,必须将其打开以进行大文件传输,否则 Java 客户端会尝试像您描述的那样将整个文件缓冲在内存中。如果您只有 .NET 客户端,它会为您处理。
  • 好的。感谢你的回答。我实际上通过从 FileStream 继承并覆盖 Read() 方法来测试您之前的答案。使用这个类而不是 FileStream,我看到了对服务上重写的 Read 方法的调用(通过破坏重写的代码),而客户端上调用了 Read。这证明你的陈述是正确的。再次感谢
猜你喜欢
  • 2011-01-27
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
相关资源
最近更新 更多