简体   繁体   English

在asp.net中分块FileUpload

[英]Chunking a FileUpload in asp.net

I've a website which allows file uploads up to 1gb and at the moment it reads the file into a Filestream and then writes it to the MSSQL database as binary content. 我有一个网站,允许上传文件的最大大小为1gb,现在它将文件读入Filestream,然后将其作为二进制内容写入MSSQL数据库。

I've found this is increasingly taking up large amount of resources so I investigated 'chunking' the file, so that it goes in 4mb chunks. 我发现这越来越占用大量资源,因此我调查了“分块”文件的过程,以便将文件分成4mb。

I've got it so the chunks go to the database, but it now takes twice as long to upload as its going from the FileUpload control to the FileStream, once its there is then starts writing this in chunks to the database. 我已经知道了,以便将块发送到数据库,但是现在上传所需的时间是从FileUpload控件上传到FileStream的时间的两倍,一旦可以上传,就开始将其以块的形式写入数据库。

Ideally I want it to to chunk direct from the FileUpload, so that say when 4mb is in the InputStream, it starts writing to the database. 理想情况下,我希望它直接从FileUpload进行分块,以便说InputStream中有4mb时,它开始写入数据库。 Here is what I've tested so far: 到目前为止,这是我测试过的内容:

        Stream fs = FileUpload.PostedFile.InputStream;

        int BUFFER_SIZE = 4000;
        byte[] chunk = new byte[BUFFER_SIZE];

        SqlConnection connection = new  SqlConnection(ConfigurationSettings.AppSettings["SQLConnection"]);
        connection.Open();
        SqlCommand cmd = new SqlCommand("UPDATE TABLENAME SET Content.WRITE(@data, NULL, 0) WHERE ID ='" + DocID + "'", connection);

        SqlParameter dataParam = cmd.Parameters.Add("@data", SqlDbType.VarBinary); // remaining as Update.WRITE
        SqlParameter lengthParam = cmd.Parameters.Add("@length", SqlDbType.Int);

        int cIndex = 0;
        int readBytes = 0;
        int fileSize = System.Convert.ToInt32(fs.Length);

        while (cIndex < fileSize)
        {
            if (cIndex + BUFFER_SIZE > fileSize)
                readBytes = fileSize - cIndex;
            else
                readBytes = BUFFER_SIZE;
            fs.Read(chunk, 0, readBytes);

            dataParam.Value = chunk;
            dataParam.Size = readBytes;
            lengthParam.Value = readBytes;

            cmd.ExecuteNonQuery();

            cIndex += BUFFER_SIZE;
        }

So to clarify, I'm awaiting for the PostedFile to fully upload the file before I can then start sending it to the DB. 因此,为了澄清起见,我等待发布文件完全上传文件,然后再开始将其发送到数据库。

  FileUpload.PostedFile.InputStream;

Can anyone point me in the right direction? 谁能指出我正确的方向?

Many thanks. 非常感谢。

Due to the way a FileUpload control works, I don't think this can be done via a webbrowser (it gets the file file from the request, as can be seen in the source) 由于FileUpload控件的工作方式,我认为无法通过网络浏览器完成此操作(它从请求中获取文件文件,如在源代码中可以看到的)

public System.Web.HttpPostedFile PostedFile
{
    get
    {
        if !(this.Page == null) && (this.Page.IsPostBack) 
        {
            return this.Context.Request.Files.Item(this.UniqueID);
        }
        return null;
    }
}

I once made this work using a native client using the following steps: 我曾经使用本地客户端通过以下步骤完成这项工作:

client: 客户:

  • Get upload token 获取上传令牌
  • start uploading chunks (of your preferred size, though i suggest something max filesize / 10, so you can give your user feedback of how much has been uploaded) 开始上传块(您希望的大小,尽管我建议最大文件大小为10),以便您可以向用户反馈上传了多少块

server: 服务器:

  • Provide token, store in dictionary or sortalike 提供令牌,存储在字典中或类似
  • Add received chunk to file with token as name 将接收到的块添加到文件中,并将令牌作为名称
  • return if file/chunk has arrived properly 如果文件/块已正确到达,则返回

Hope this'll help you in some way :). 希望这会对您有所帮助:)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM