我有一个WCF服务,它有一个方法返回一个流。
[ServiceContract]
public interface IService1
{
[OperationContract]
MyMessage Test();
}
现在,MyMessage
的定义如下:
[MessageContract]
public class MyMessage
{
public MyMessage(string file)
{
this.Stream = File.OpenRead(file);
this.Length = Stream.Length;
}
[MessageHeader]
public long Length;
[MessageBodyMember]
public Stream Stream;
}
桃色。
该服务使用basicHttpBinding
进行流式响应。这是绑定配置:
<basicHttpBinding>
<binding name="BasicStreaming"
maxReceivedMessageSize="67108864" maxBufferSize="65536" transferMode="StreamedResponse" />
</basicHttpBinding>
现在,这就是事情开始变得有趣的地方。调用此服务时,如果我以特定方式读取流,最后一个字节将丢失。以下是说明两种不同方法的代码:
Service1Client client = new Service1Client();
//this way the last byte is lost
Stream stream1;
var length = client.Test(out stream1);
var buffer1 = new byte[length];
stream1.Read(buffer1, 0, (int)length);
File.WriteAllBytes("test1.txt", buffer1);
stream1.Close();
//here i receive all bytes
Stream stream2;
length = client.Test(out stream2);
var buffer2 = new byte[length];
int c = 0, b;
while ((b = stream2.ReadByte()) != -1)
{
buffer2[c++] = (byte)b;
}
File.WriteAllBytes("test2.txt", buffer2);
stream2.Close();
我确信我错过了一些东西,但有人能指出我究竟发生这种情况的原因吗?最大的问题是,在另一个服务中,无论我以哪种方式读取流,我都会丢失最后一个字节,但也许通过识别问题我也可以解决这个问题。
技术细节:
注意:我上传了隔离问题的项目,所以任何人都可以尝试一下:mediafire
答案 0 :(得分:1)
我没有一个确切的答案,为什么这个有效(我的大脑目前没有充分参与),但这可行:
var buffer1 = new byte[length+2];
stream1.Read(buffer1, 0, buffer1.Length);
(并且,是的,你最终会得到一个太大的缓冲区。这只是进一步思考的起点)
在测试中我发现+1不够大,但+2是。
答案 1 :(得分:0)
为什么传递(长度+ 1)的计数?它应该是长度,否则你试图读取比可用字节多一个字节。