一个流中的多个流将无法正确传递给客户端 [英] Multiple stream in one stream will not passed to client properly

查看:51
本文介绍了一个流中的多个流将无法正确传递给客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在WCF服务中,我根据> 此问题 就像:

In WCF service I fill Stream according to this question like :

   result.Stream = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(result.Stream);
            foreach (string fileN in zipFiles)
            {
                byte[] fileBytes = File.ReadAllBytes(fileN);
                writer.Write(BitConverter.GetBytes(fileBytes.Length), 0, 4);
                writer.Write(fileBytes, 0, fileBytes.Length);
            }
            writer.Flush();
            return result; 

在此之前,我通过此方法返回流,并且一切都在服务端和客户端起作用:

before this I was returning stream by this and everything works in service and client side:

 result.Stream = new MemoryStream(File.ReadAllBytes(fileN));

流为 MessageBodyMember 但是螺母现在将其更改为将所有文件保存在一个流中.

Stream be MessageBodyMember but nut now changed it to save all file in one stream.

和客户端的测试方法:

 ExportClient export = new ExportClient("exportEndPoint");
        ExportResult_C result = export.Export(source);
        result.Stream.Position = 0;
        //result.Stream.SaveToFile("d:\\kkk.log");
        BinaryReader reader = new BinaryReader(result.Stream, System.Text.Encoding.UTF8);
        string pathToSave = string.Empty;
        while (result.Stream.Position < result.Stream.Length)
        {
            int size = reader.ReadInt32();
            byte[] data = reader.ReadBytes(size);
            pathToSave = "D:\\test\\" + new Random().Next(0, 2564586).ToString() + ".zip";
            File.WriteAllBytes(pathToSave, data);
        }

端点地址:

 <endpoint address="net.tcp://localhost:2082/Exchange/Export.svc" binding="netTcpBinding" bindingConfiguration="largeSizeStreamTcp"
    contract="xxx" name="exportEndPoint"/>

和绑定配置:

 <netTcpBinding>
    <binding openTimeout="00:00:03" maxReceivedMessageSize="2000000000" transferMode="Streamed" maxBufferSize="2000000000" >
      <readerQuotas maxDepth="32" maxArrayLength="2000000000" maxStringContentLength="2000000000" />
      <security mode="None" />
    </binding>
    <binding name="largeSizeStreamTcp"  transferMode="Streamed" receiveTimeout="00:30:00" sendTimeout="00:30:00" openTimeout="00:00:01" maxReceivedMessageSize="2000000000" maxBufferSize="2000000000" >
      <readerQuotas maxDepth="32" maxArrayLength="2000000000" maxStringContentLength="2000000000" />
      <security mode="None" />
    </binding>
  </netTcpBinding>
  <netNamedPipeBinding>

我相信端点和绑定是正确的,因为我能够返回一个文件流并将其保存回去,但是现在服务端没有问题,但是当它从客户端获得时,Stream丢失了它的内容,长度,位置

I believe endpoint and binding is correct as I was able to return one file stream and save it back but now there is no prob in service side but when it will get from client side, Stream got lost it's content,length,position.

这真的把我逼到了墙上!

this is really drive me up the wall!!!

有人知道为什么发生这种情况吗(在客户端)?

does anyone know why this is occurred(in client side) ?

推荐答案

好吧,最后,我成功地成功实现了我们的方案,将答案放在这里,也许有人想使用该解决方案在一个流中返回多个文件.

Wooow, Finally I get success to implement our scenario properly, going to put the answer here maybe someone wants to use the solution to returns multiple files in one stream.

有几个示例可以返回多个文件,但是所有示例都可以返回字节数组,由于很多原因,我更喜欢返回流,重要的是,对于大型文件,流的性能更好,因为不需要读取所有文件一次进入内存并向后兼容我的情况.

there are several sample to return multiple files but all of them are returning byte array, I prefer to return stream because of many reason, the important thing is streams will perform better for large files since not all of it needs to be read into memory at one time and backward compatibility for my case.

因此,在第一步中,我创建了一个可序列化的 DataContract 来保存文件名及其内容字节.

So at the first step I have created a serializable DataContract to hold the name of file and it's content byte.

[DataContract]
[Serializable]
public class ExportSourceFiles_C
{
    [DataMember]
    public string Name;
    [DataMember]
    public byte[] Content;
}

在第二步 中,将创建一个 ExportSourceFile_C 列表,如下所示:

at the second step a list of ExportSourceFile_C will be created like:

List<ExportSourceFiles_C> sourceFiles = new List<ExportSourceFiles_C>();
string[] zipFiles = Directory.GetFiles(zipRoot);
foreach (string path in zipFiles)
  {
     byte[] fileBytes = File.ReadAllBytes(path);
     sourceFiles.Add(new ExportSourceFiles_C()
     {
         Name = Path.GetFileName(path),
         Content = fileBytes
     });
  }

第三步中,应将提及的列表序列化为 result.Stream ,例如:

at the third step the mentioned list should be serialized to result.Stream like:

  result.Stream = new MemoryStream();
  BinaryFormatter formatter = new BinaryFormatter();
  formatter.Serialize(result.Stream, sourceFiles);
  result.Stream.Position = 0;
  return result;

在客户端这足以将流反序列化为 ExportSourceFiles_C 的列表,因此客户端的最后一步应该是这样的:

in client side this is enough deserialize the stream to list of ExportSourceFiles_C so the last step in client side should be something like this:

 ExportClient export = new ExportClient("exportEndPoint");
 ExportResult_C result = export.Export(source);
 BinaryFormatter formatter = new BinaryFormatter();
 List<ExportSourceFiles_C> deserialisedFiles = (List<ExportSourceFiles_C>)formatter.Deserialize(result.Stream);
 foreach (ExportSourceFiles_C file in deserialisedFiles)
      File.WriteAllBytes("d:\\" + file.Name, file.Content);

所有内容都像魅力一样,毫无问题.

everything works like a charm without any problem.

享受.

这篇关于一个流中的多个流将无法正确传递给客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆