简体   繁体   中英

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.

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.

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.

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. 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)

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)

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 :).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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