将大文件发送到WCF服务,反之亦然 [英] Send large file to WCF service and vise versa
问题描述
各位大家好!
我尝试从客户端向WCF服务发送非常大的文件(大约4 GB)。
但我收到有关内存不足的错误。我应该将整个文件分成几部分吗?
代码片段:
客户端:< br $>
WCFClient.ServiceReference1.FileTransferServiceClient client =
new WCFClient.ServiceReference1.FileTransferServiceClient();
string uploadfilename =Upload.txt;
using(FileStream fs = new FileStream(@C:\+ uploadfilename,FileMode.Open,FileAccess.Read,FileShare.Read))
{
client。 UploadFile(uploadfilename,fs); < font color =red> //我有错误!!!< / font>
}
服务器端:
[ServiceContract]
public interface IFileTransferService
{
[OperationContract(IsOneWay = true)]
void UploadFile(FileUploadMessage request);
[OperationContract(IsOneWay = false)]
FileDownloadReturnMessage DownloadFile(FileDownloadMessage request);
}
[MessageContract]
public class FileUploadMessage
{
[MessageHeader(MustUnderstand = true)]
public string Filename;
[MessageBodyMember(Order = 1)]
public Stream FileByteStream;
}
[MessageContract]
公共类FileDownloadMessage
{
[MessageHeader(MustUnderstand = true)]
public string Filename;
}
[MessageContract]
公共类FileDownloadReturnMessage
{
public FileDownloadReturnMessage(string filename,Stream stream)
{
this.DownloadedFilename = filename;
this.FileByteStream = stream;
}
[MessageHeader(MustUnderstand = true)]
公共字符串DownloadedFilename;
[MessageBodyMember(Order = 1)]
public Stream FileByteStream;
}
公共类ServiceClass:IFileTransferServiceMarco
{
public void UploadFile(FileUploadMessage request)
{
// try
{
string basePath = @C:\Downloads;
string serverFileName = Path.Combine(basePath,request.Filename);
using(FileStream outfile = new FileStream(serverFileName,FileMode.Create))
{
const int bufferSize = 65536; // 64K
Byte [] buffer = new Byte [bufferSize];
int bytesRead = request.FileByteStream.Read(buffer,0,bufferSize);
while(bytesRead> 0)
{
outfile.Write(buffer,0,bytesRead);
bytesRead = request.FileByteStream.Read(buffer,0,bufferSize);
}
}
}
// catch(IOException e)
{
//抛出新的FaultException< ioexception>(e);
}
}
public FileDownloadReturnMessage DownloadFile(FileDownloadMessage request)
{
string localFileName = request.Filename;
try
{
string basePath = @C:\Downloads;
string serverFileName = Path.Combine(basePath,request.Filename);
Stream fs = new FileStream(serverFileName,FileMode.Open);
返回新的FileDownloadReturnMessage(request.Filename,fs);
}
catch(IOException e)
{
抛出新的FaultException< ioexception>(e);
}
}
}< / ioexception>< / ioexception>
和app .config:
endpoint address =winceStream
binding =basicHttpBinding
bindingConfiguration =HttpBinding_MTOM
contract =EssentialWCF.IFileTransferService
....
bindings
basicHttpBinding
binding name =HttpBinding_MTOMmessageEncoding =MtomtransferMode =StreamedmaxReceivedMessageSize = 4294967294 >
绑定
basicHttpBinding
绑定
有人能帮助我吗?
对不起我的英文:)
您可以尝试在配置中增加ReaderQuota中的值。可能会有帮助。
BTW,你应该使用Streaming而不是MTOM来发送大文件恕我直言。我尝试过MSDN帮助,但找不到一个像样的例子。 这 [ ^ 是我能找到的那个。我记得在MSDN论坛上读过一个叫Carlos的人的帖子。他也为流媒体文件发布了一个非常好的代码示例。虽然找不到那篇文章。如果我可以点击它,我会更新回复。
我已经解决了我的问题!
你应该添加maxBufferSize和app.config文件中的maxReceivedMessageSize。
例如:
客户端:
< bindings >
< basicHttpBinding >
< binding name = BasicHttpBinding_IFileTransferServiceMarco < span class =code-attribute> closeTimeout = 00:01:0 0
openTimeout = 00:01:00receiveTimeout = 00:10:00 sendTimeout = 00:10:00
< span class =code-attribute> allowCookies = false bypassProxyOnLocal = false hostNameComparisonMode = StrongWildcard
maxBufferSize = 65536 maxBufferPoolSize = 524288 maxReceivedMessageSize = 4294967294
messageEncoding = 文字 textEncoding = utf-8 transferMode = 流
useDefaultWebProxy = true >
< readerQuotas maxDepth = 32 maxStringContentLength = 8192 maxArrayLength = 16384
< span class =code-attribute> maxBytesPerRead = 4096 maxNameTableCharCount < span class =code-keyword> = 1 6384 / >
< security mode = 无 >
< transport clientCredentialType = 无 proxyCredentialType = 无
< span class =code-attribute> realm = / >
< 消息 clientCredentialType = 用户名 algorithmSuite = 默认 / >
< / security >
< / binding >
< / basicHttpBinding >
< / bindings >
< 端点 地址 = http:// localhost:8080 / EssentialWCF / winceStream
binding = basicHttpBinding bindingConfiguration = BasicHttpBinding_IFileTransferServiceMarco
< span class =code-attribute> 合同 = ServiceReference1.IFileTransferServiceMarco name = BasicHttpBinding_IFileTransferServiceMarco / >
服务器端:
< 绑定 >
< basicHttpBinding >
< binding < span class =code-attribute> name = HttpBinding_MTOM messageEncoding = 文本 transferMode = 流式 maxReceivedMessageSize = 4294967294
maxBufferSize = 65536 maxBufferPoolSize = 65536
< span class =code-attribute> < / binding >
< / basicHttpBinding >
< / bindings >
< endpoint 地址 = winceStream
binding = basicHttpBinding
bindingConfiguration = HttpBinding_MTOM
< span class =code-attribute> 合同 = EssentialWCF.IFileTransferServiceMarco / < span class =code-keyword>>
祝你好运!
< blockquote>
我' 解决了我的问题!
您应该在app.config文件中添加maxBufferSize和maxReceivedMessageSize。
<绑定>
< basichttpbinding>
< binding name =BasicHttpBinding_IFileTransferServiceMarcoclosetimeout =00:01:00>
openTimeout =00:01:00receiveTimeout =00:10:00sendTimeout =00:10:00
allowCookies =falsebypassProxyOnLocal =falsehostNameComparisonMode =StrongWildcard
maxBufferSize =65536maxBufferPoolSize =524288maxReceivedMessageSize =4294967294
messageEncoding =TexttextEncoding =utf-8transferMode =Streamed
useDefaultWebProxy =true>
< readerquotas maxdepth =32maxstringcontentlength =8192maxarraylength =16384>
maxBytesPerRead = 4096maxNameTableCharCount =16384 />
< security mode =None>
< transport clientcredentialtype =Noneproxycredentialtype =None> realm =/>
< message clientcredentialtype =UserNamealgorithmsuite =Default>
< endpoint address =http:// localhost:8080 / EssentialWCF / winceStream>
binding = basicHttpBindingbindingConfiguration =BasicHttpBinding_IFileTransferServiceMarco
contract =ServiceReference1.IFileTransferServiceMarconame =BasicHttpBinding_IFileTransferServiceMarco/>
< bindings>
< basichttpbinding>
< binding name = HttpBinding_MTOMmessageencoding =Texttransfermode =Streamedmaxreceivedmessagesize =4294967294>
maxBufferSize =65536maxBufferPoolSize =65536
< e ndpoint address =winceStream>
binding =basicHttpBinding
bindingConfiguration =HttpBinding_MTOM
contract =EssentialWCF.IFileTransferServiceMarco/ >
Hello everybody!
I try to send very big file(about 4 GB) to WCF service from client.
But I get error about low memory. Should I separate whole file into the parts or not?
code snippet:
Client side:
WCFClient.ServiceReference1.FileTransferServiceClient client= new WCFClient.ServiceReference1.FileTransferServiceClient(); string uploadfilename = "Upload.txt"; using (FileStream fs = new FileStream(@"C:\"+uploadfilename, FileMode.Open, FileAccess.Read, FileShare.Read)) { client.UploadFile(uploadfilename, fs); <font color="red">// There is I have an error!!!</font> }
Server side:
[ServiceContract] public interface IFileTransferService { [OperationContract(IsOneWay = true)] void UploadFile(FileUploadMessage request); [OperationContract(IsOneWay = false)] FileDownloadReturnMessage DownloadFile(FileDownloadMessage request); } [MessageContract] public class FileUploadMessage { [MessageHeader(MustUnderstand = true)] public string Filename; [MessageBodyMember(Order = 1)] public Stream FileByteStream; } [MessageContract] public class FileDownloadMessage { [MessageHeader(MustUnderstand = true)] public string Filename; } [MessageContract] public class FileDownloadReturnMessage { public FileDownloadReturnMessage(string filename, Stream stream) { this.DownloadedFilename = filename; this.FileByteStream = stream; } [MessageHeader(MustUnderstand = true)] public string DownloadedFilename; [MessageBodyMember(Order = 1)] public Stream FileByteStream; } public class ServiceClass : IFileTransferServiceMarco { public void UploadFile(FileUploadMessage request) { //try { string basePath = @"C:\Downloads"; string serverFileName = Path.Combine(basePath, request.Filename); using (FileStream outfile = new FileStream(serverFileName, FileMode.Create)) { const int bufferSize = 65536; // 64K Byte[] buffer = new Byte[bufferSize]; int bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize); while (bytesRead > 0) { outfile.Write(buffer, 0, bytesRead); bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize); } } } // catch (IOException e) { // throw new FaultException<ioexception>(e); } } public FileDownloadReturnMessage DownloadFile(FileDownloadMessage request) { string localFileName = request.Filename; try { string basePath = @"C:\Downloads"; string serverFileName = Path.Combine(basePath, request.Filename); Stream fs = new FileStream(serverFileName, FileMode.Open); return new FileDownloadReturnMessage(request.Filename, fs); } catch (IOException e) { throw new FaultException<ioexception>(e); } } }</ioexception></ioexception>
and app.config:
endpoint address="winceStream" binding="basicHttpBinding" bindingConfiguration="HttpBinding_MTOM" contract="EssentialWCF.IFileTransferService" .... bindings basicHttpBinding binding name="HttpBinding_MTOM" messageEncoding="Mtom" transferMode="Streamed" maxReceivedMessageSize="4294967294"> binding basicHttpBinding bindings
Could anybody help me?
Sorry for my English :)
You can try increasing the values in ReaderQuota in your configuration. Might help.
BTW, you should be using Streaming rather than MTOM for sending large files IMHO. I tried MSDN help but could not find a decent example. This[^] is the one I could find. I remember reading a post from a guy called Carlos on MSDN forums. He too had posted a very good code sample for streaming file. Cannot find that post though. I will update the reply if I can hit it.
I''ve solved my problem!
You should add maxBufferSize and maxReceivedMessageSize in your app.config file.
For example:
Client side:
<bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IFileTransferServiceMarco" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="4294967294" messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding> </bindings> <endpoint address="http://localhost:8080/EssentialWCF/winceStream" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IFileTransferServiceMarco" contract="ServiceReference1.IFileTransferServiceMarco" name="BasicHttpBinding_IFileTransferServiceMarco" />
Server side:
<bindings> <basicHttpBinding> <binding name="HttpBinding_MTOM" messageEncoding="Text" transferMode="Streamed" maxReceivedMessageSize="4294967294" maxBufferSize="65536" maxBufferPoolSize="65536" </binding> </basicHttpBinding> </bindings> <endpoint address="winceStream" binding="basicHttpBinding" bindingConfiguration="HttpBinding_MTOM" contract="EssentialWCF.IFileTransferServiceMarco" />
Good luck!
I've solved my problem! You should add maxBufferSize and maxReceivedMessageSize in your app.config file.
<bindings>
<basichttpbinding>
<binding name="BasicHttpBinding_IFileTransferServiceMarco" closetimeout="00:01:00">
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="4294967294"
messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed"
useDefaultWebProxy="true">
<readerquotas maxdepth="32" maxstringcontentlength="8192" maxarraylength="16384">
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientcredentialtype="None" proxycredentialtype="None"> realm="" />
<message clientcredentialtype="UserName" algorithmsuite="Default">
<endpoint address="http://localhost:8080/EssentialWCF/winceStream">
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IFileTransferServiceMarco"
contract="ServiceReference1.IFileTransferServiceMarco" name="BasicHttpBinding_IFileTransferServiceMarco" />
<bindings>
<basichttpbinding>
<binding name="HttpBinding_MTOM" messageencoding="Text" transfermode="Streamed" maxreceivedmessagesize="4294967294">
maxBufferSize="65536" maxBufferPoolSize="65536"
<endpoint address="winceStream">
binding="basicHttpBinding"
bindingConfiguration="HttpBinding_MTOM"
contract="EssentialWCF.IFileTransferServiceMarco" />
这篇关于将大文件发送到WCF服务,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!