. NET Framework MVC Загрузка большого файла - PullRequest
2 голосов
/ 11 марта 2020

Я пытаюсь загрузить большие двоичные файлы из веб-клиента в. NET 4.6.1 Framework MVC API. Эти файлы могут варьироваться от 5 до 20 ГБ.

Я попытался разбить файл на куски, чтобы загрузить каждый кусок и объединить результаты в конце, но объединенный файл всегда поврежден. Если я работаю с небольшими файлами и не разделяю, двоичный файл будет работать правильно. Тем не менее, когда я разделяю и объединяю файл «поврежден». Он не будет загружаться или вести себя как ожидалось.

Я просмотрел все и не нашел правильного решения этого вопроса, поэтому я надеюсь, что кто-то может помочь мне здесь.

Я следовал этому https://forums.asp.net/t/1742612.aspx?How+to+upload+a+big+file+in+Mvc, но не могу заставить его работать, и исправленное решение так и не было опубликовано. Я отслеживаю порядок файлов перед слиянием на сервере.

Javascript (вызов для uploadData сделан для инициации)

       function uploadComplete(file) {
            var formData = new FormData();
            formData.append('fileName', file.name);
            formData.append('completed', true);

            var xhr3 = new XMLHttpRequest();
            xhr3.open("POST", "api/CompleteUpload", true); //combine the chunks together
            xhr3.send(formData);

            return;
        }

        function uploadData(item) {           
            var blob = item.zipFile;
            var BYTES_PER_CHUNK = 750000000; // sample chunk sizes.
            var SIZE = blob.size;

            //upload content
            var start = 0;
            var end = BYTES_PER_CHUNK;
            var completed = 0;
            var count = SIZE % BYTES_PER_CHUNK == 0 ? SIZE / BYTES_PER_CHUNK : Math.floor(SIZE / BYTES_PER_CHUNK) + 1;

            while (start < SIZE) {
                var chunk = blob.slice(start, end);
                var xhr = new XMLHttpRequest();
                xhr.onload = function () {
                    completed = completed + 1;
                    if (completed === count) {
                        uploadComplete(item.zipFile);
                    }
                };
                xhr.open("POST", "/api/MultiUpload", true);
                xhr.setRequestHeader("contentType", false);
                xhr.setRequestHeader("processData", false);
                xhr.send(chunk);

                start = end;
                end = start + BYTES_PER_CHUNK;
            }
        } 

Контроллер сервера

    //global vars
    public static List<string> myList = new List<string>();

    [HttpPost]
    [Route("CompleteUpload")]
    public string CompleteUpload()
    {
        var request = HttpContext.Current.Request;

        //verify all parameters were defined

        var form = request.Form;

        string fileName;
        bool completed;
        if (!string.IsNullOrEmpty(request.Form["fileName"]) &&
            !string.IsNullOrEmpty(request.Form["completed"]))
        {
            fileName = request.Form["fileName"];
            completed = bool.Parse(request.Form["completed"]);
        }
        else
        {
            return "Invalid upload request";
        }

        if (completed)
        {
            string path = HttpContext.Current.Server.MapPath("~/Data/uploads/Tamp");
            string newpath = Path.Combine(path, fileName);
            string[] filePaths = Directory.GetFiles(path);

            foreach (string item in myList)
            {
                MergeFiles(newpath, item);
            }
        }

        //Remove all items from list after request is done
        myList.Clear();
        return "success";
    }

    private static void MergeFiles(string file1, string file2)
    {
        FileStream fs1 = null;
        FileStream fs2 = null;
        try
        {
            fs1 = System.IO.File.Open(file1, FileMode.Append);
            fs2 = System.IO.File.Open(file2, FileMode.Open);
            byte[] fs2Content = new byte[fs2.Length];
            fs2.Read(fs2Content, 0, (int)fs2.Length);
            fs1.Write(fs2Content, 0, (int)fs2.Length);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message + " : " + ex.StackTrace + " " + file2);
        }
        finally
        {
            if(fs1 != null) fs1.Close();
            if (fs2 != null)
            {
                fs2.Close();
                System.IO.File.Delete(file2);
            }
        }
    }

    [HttpPost]
    [Route("MultiUpload")]
    public string MultiUpload()
    {
        try
        {                
            var request = HttpContext.Current.Request;
            var chunks = request.InputStream;

            string path = HttpContext.Current.Server.MapPath("~/Data/uploads/Tamp");
            string fileName = Path.GetTempFileName();
            string newpath = Path.Combine(path, fileName);
            myList.Add(newpath);

            using (System.IO.FileStream fs = System.IO.File.Create(newpath))
            {
                byte[] bytes = new byte[77570];

                int bytesRead;
                while ((bytesRead = request.InputStream.Read(bytes, 0, bytes.Length)) > 0)
                {
                    fs.Write(bytes, 0, bytesRead);
                }
            }
            return "test";
        }
        catch (Exception exception)
        {
            return exception.Message;
        }
    }
...