我们有一个Web服务(asmx),它接受字节数组缓冲区并将其流到外部文件服务中进行存储和归档。它是由一个生成相当小的文件(3-5米)的Windows服务调用的,因此创建一个大小大小的字节数组并将其作为对web服务调用的param提供给它,到目前为止一直很有效。
我的任务是向文件队列中添加一个新作业,这可能会生成大于7000万的文件。显然,这种大小的byte[]会淹没系统内存,所以我一直在寻找解决方案。web服务有一个内部方法,它将FileStream作为param而不是byte[],因此我尝试将FileStream方法作为WebMethod来处理。我已经更新了Windows中的引用,但是发生了一件奇怪的事情: FileStream参数附带了一个名称空间说明符(类似于CallingWindowsService.ExternalWebServiceFileManager.FileStream),而这个指定的对象不使用任何文件名作为构造函数,因此我不能打开特定的文件。
我完全不知道该怎么处理这件事。有没有其他人这样做过--将大量数据传输到web服务--如果是的话,最好的方法是什么?我的web服务需要一个byte[]或FileStream。
通过查看其他一些消息,看起来MTOM (不熟悉它)可能是一个解决方案,但我不知道如何在我的web方法中设置它或使它工作。
发布于 2012-04-12 01:47:00
您可以尝试一些东西,不要提到您使用的是什么协议或如何托管它,所以我假设它可能是IIS7和您使用的soap。在web服务的web.config文件中,可以添加以下内容,这将增加允许传输的文件大小,而不会出现404错误:
<system.web>
<httpRuntime executionTimeout="999999" maxRequestLength="2097151" />
...
</system.web>为了允许大文件传输,您可能需要对web服务的web.config文件做第二件事:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2000000000" />
</requestFiltering>
</security>
</system.webServer>另一种可能性是:
<location path="Copy.asmx"> <!-- Name of you asmx -->
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="104857600"/> <!-- 100 megs -->
</requestFiltering>
</security>
</system.webServer>
</location>通过web服务发送byte[]的主要问题是,它们被放入SOAP主体中,soap主体被编码为一个基本的64字符串。像这样的编码文件会使文件在soap主体中的大小增加三分之二(也就是说,一个6MB文件通过网络变成一个9MB文件)。
另一种可能是“分块”在传输之前将数据分割成较小的段,这可能是您所需要的。基于网络速度、服务器资源等因素,chunkSize (设置为500 key )可以成为提高上传性能的关键因素。
/// <summary>
/// Chunk the file and upload
/// </summary>
/// <param name="filename"></param>
private void UploadVideo(string filename)
{
#region Vars
const int chunkSize = 512000;
byte[] bytes = null;
int startIndex, endIndex, length, totalChunks;
WS.UploadRequest objRequest = new WS.UploadRequest();
#endregion
try
{
if (File.Exists(filename))
{
using (WS.UploadService objService = new WS.UploadService())
{
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
//// Calculate total chunks to be sent to service
totalChunks = (int)Math.Ceiling((double)fs.Length / chunkSize);
//// Set up Upload request object
objRequest.FileName = filename;
objRequest.FileSize = fs.Length;
for (int i = 0; i < totalChunks; i++)
{
startIndex = i * chunkSize;
endIndex = (int)(startIndex + chunkSize > fs.Length ? fs.Length : startIndex + chunkSize);
length = endIndex - startIndex;
bytes = new byte[length];
//// Read bytes from file, and send upload request
fs.Read(bytes, 0, bytes.Length);
objRequest.FileBytes = bytes;
objService.UploadVideo(objRequest);
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Error- {0}", ex.Message));
}发布于 2012-04-11 23:17:37
ASMX web服务是一种遗留技术,不应用于新的开发。
它缺乏的一个特性是对流和大文件的支持。特别是,在发送到客户端的路上,在内存中最多会重复四次消息。
WCF确实支持真正的流。
发布于 2012-04-12 01:19:59
正如@John所说,web服务对流和大文件处理的支持很差,您可以使用压缩来通过web服务传输文件,而不是发送原始文件。
https://stackoverflow.com/questions/10115011
复制相似问题