首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将大文件流到Web服务

将大文件流到Web服务
EN

Stack Overflow用户
提问于 2012-04-11 22:43:00
回答 3查看 16K关注 0票数 7

我们有一个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方法中设置它或使它工作。

EN

回答 3

Stack Overflow用户

发布于 2012-04-12 01:47:00

您可以尝试一些东西,不要提到您使用的是什么协议或如何托管它,所以我假设它可能是IIS7和您使用的soap。在web服务的web.config文件中,可以添加以下内容,这将增加允许传输的文件大小,而不会出现404错误:

代码语言:javascript
复制
  <system.web>
     <httpRuntime executionTimeout="999999" maxRequestLength="2097151" />
     ...
  </system.web>

为了允许大文件传输,您可能需要对web服务的web.config文件做第二件事:

代码语言:javascript
复制
  <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="2000000000" />
      </requestFiltering>
    </security>
  </system.webServer>

另一种可能性是:

代码语言:javascript
复制
<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 )可以成为提高上传性能的关键因素。

代码语言:javascript
复制
/// <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));
    }
票数 3
EN

Stack Overflow用户

发布于 2012-04-11 23:17:37

ASMX web服务是一种遗留技术,不应用于新的开发。

它缺乏的一个特性是对流和大文件的支持。特别是,在发送到客户端的路上,在内存中最多会重复四次消息。

WCF确实支持真正的流。

票数 2
EN

Stack Overflow用户

发布于 2012-04-12 01:19:59

正如@John所说,web服务对流和大文件处理的支持很差,您可以使用压缩来通过web服务传输文件,而不是发送原始文件。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10115011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档