我需要将一个大文件上传到Azure存储。作为第一步,我试图通过wcf服务将文件上传到web服务文件夹。我按照此链接Streaming files over WCF中的步骤进行操作。我的服务代码:
namespace MilkboxGames.Services
{
[ServiceContract]
public interface IFileUploadService
{
[OperationContract]
UploadResponse Upload(UploadRequest request);
}
[MessageContract]
public class UploadRequest
{
[MessageHeader(MustUnderstand = true)]
public string BlobUrl { get; set; }
[MessageBodyMember(Order = 1)]
public Stream data { get; set; }
}
[MessageContract]
public class UploadResponse
{
[MessageBodyMember(Order = 1)]
public bool UploadSucceeded { get; set; }
}
}
和
namespace MilkboxGames.Services
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class FileUploadService : IFileUploadService
{
#region IFileUploadService Members
public UploadResponse Upload(UploadRequest request)
{
try
{
string uploadDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
string path = Path.Combine(uploadDirectory, "zacharyxu1234567890.txt");
if (File.Exists(path))
{
File.Delete(path);
}
const int bufferSize = 2048;
byte[] buffer = new byte[bufferSize];
using (FileStream outputStream = new FileStream(path, FileMode.Create, FileAccess.Write))
{
int bytesRead = request.data.Read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
outputStream.Write(buffer, 0, bytesRead);
bytesRead = request.data.Read(buffer, 0, bufferSize);
}
outputStream.Close();
}
return new UploadResponse
{
UploadSucceeded = true
};
}
catch (Exception ex)
{
return new UploadResponse
{
UploadSucceeded = false
};
}
}
#endregion
}
}
的Web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="false" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" executionTimeout="600"
maxRequestLength="2097152" />
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="FileUploadServiceBinding" messageEncoding="Mtom" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" receiveTimeout="00:15:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00" transferMode="Streamed">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MilkboxGames.Services.FileUploadService" behaviorConfiguration="FileUploadServiceBehavior">
<endpoint address=""
binding="basicHttpBinding" contract="MilkboxGames.Services.IFileUploadService" bindingConfiguration="FileUploadServiceBinding">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="FileUploadServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483648" />
</requestFiltering>
</security>
</system.webServer>
</configuration>
要使用此服务,我创建了一个控制台应用程序并将wcf服务添加到服务引用。我注意到服务方法变成了公共bool上传(字符串BlobUrl,System.IO.Stream数据)&#39;而不是公共UploadResponse上传(UploadRequest请求)&#39;。有人可以向我解释原因吗?
客户代码:
string blobUrl = "assassinscreedrevelationsandroid/GT-I9100G/assassinscreedrevelationsandroid.apk";
string fileName = "C:\\ws_new\\XuConsoleApplication\\XuConsoleApplication\\bin\\Debug\\motutcimac.myar";
bool bUploadBlobResult;
byte[] buffer = File.ReadAllBytes(fileName);
Console.WriteLine("Size = " + buffer.Length);
Stream fileStream = System.IO.File.OpenRead(fileName);
FileUploadServiceClient objFileUploadServiceClient = new FileUploadServiceClient();
bUploadBlobResult = objFileUploadServiceClient.Upload(blobUrl, fileStream);
我设法上传了一个123.8MB的文件。当我尝试上传354.6MB的文件时,我得到以下异常:
Unhandled Exception: System.InsufficientMemoryException: Failed to allocate
a managed memory buffer of 371848965 bytes. The amount of available memory
may be low. ---> System.OutOfMemoryException: Exception of type
'System.OutOfMemoryException' was thrown.
at System.Runtime.Fx.AllocateByteArray(Int32 size)
--- End of inner exception stack trace ---
我无法弄清楚为什么会这样。任何帮助或建议都表示赞赏。
答案 0 :(得分:0)
未处理的异常:System.InsufficientMemoryException:失败 分配371848965字节的托管内存缓冲区。大量的 可用内存可能很低。
以上消息表明您的应用正在耗尽允许的所有内存,为了增加限制,我认为您需要更大的属性值&#34; maxReceivedMessageSize&#34;
也来自另一个线程(Failed to allocate a managed memory buffer of 134217728 bytes. The amount of available memory may be low),它建议使用流传输模式进行大文件上传。
在WCF操作的消息合约中使用Stream属性进行传输 大物件。
[MessageContract]
public class DocumentDescription
{
[MessageBodyMember(Namespace = "http://example.com/App")]
public Stream Stream { get; set; }
}
Configure your binding this way
<binding name="Binding_DocumentService" receiveTimeout="03:00:00"
sendTimeout="02:00:00" transferMode="Streamed" maxReceivedMessageSize="2000000">
<security mode="Transport" />
</binding>