我需要将一个大文件上传到 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 服务添加到服务引用中。我注意到服务方法变成了“public bool Upload(string BlobUrl, System.IO.Stream data)”而不是“public UploadResponse Upload(UploadRequest request)”。有人可以向我解释一下为什么吗?
客户端代码:
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 ---
我无法弄清楚为什么会发生这种情况。如有任何帮助或建议,我们将不胜感激。
最佳答案
Unhandled Exception: System.InsufficientMemoryException: Failed to allocate a managed memory buffer of 371848965 bytes. The amount of available memory may be low.
上面的消息表明您的应用程序正在耗尽允许的所有内存,为了增加限制,我认为您需要属性“maxReceivedMessageSize”的更大值
同样来自另一个线程( Failed to allocate a managed memory buffer of 134217728 bytes. The amount of available memory may be low ),建议使用流传输模式进行大文件上传。
Use Stream property in message contract of WCF operation to transfer large objects.
[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>
关于c# - 通过 wcf 将大文件流式传输到 azure 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35444303/