使用 Fine Uploader 分块上传文件,合并后会损坏

Uploading files in chunks with Fine Uploader, corrupt when merged back together

我正在使用具有并发分块功能的 fineuploader (https://fineuploader.com) 将文件上传到服务器。对于小文件,它工作得很好,但对于大文件,我发现合并文件最终损坏的问题。

例如,我尝试了一个 2.7GB 的 Zip 文件,最终文件的字节大小完全正确,但无法提取('File is invalid' 和 'Unconfirmed start of archive')。

我也试过一个 850MB 的 PDF,但最终损坏了,无法查看。

所有 tmp 文件都上传正常,数量与 'qqtotalparts' 的预期数量相符。我已尝试将 partSize 从 2000000 更改为更大的尺寸,但仍然遇到同样的问题。

不确定哪里出错了,但如果有任何帮助或建议,我们将不胜感激!

Javascript:

var manualUploader = new qq.FineUploader({
    element: document.getElementById("fine-uploader-manual-trigger"),
    template: 'qq-template-manual-trigger',
    request: {
        endpoint: "application.aspx?p=testnewhtml5storefiles"
    },
    deleteFile: {
        enabled: true,
        endpoint: "application.aspx?p=testnewhtml5storefiles"
    },
    chunking: {
        enabled: true,
        partSize: 10000000, 
        concurrent: {
            enabled: true
        },
        success: {
            endpoint: "application.aspx?p=testnewhtml5storefiles?done=1"
        }
    },
    resume: {
        enabled: true
    },
    retry: {
        //enableAuto: true,
        showButton: true
    },
        thumbnails: {
            placeholders: {
                waitingPath: 'images/waiting-generic.png',
                notAvailablePath: 'images/not_available-generic.png'
            }
        },
        autoUpload: false,
        debug: true
});

服务器端:

Dim totalParts as integer = CInt(Request("qqtotalparts") )
Dim partIndex as integer = CInt(Request("qqpartindex") )
Dim filename as string = Request("qqfilename")
Dim totalFileSizeName As string = Request("qqtotalfilesize")

Dim uploadedTemp as string = "\testing\chunks\"
Dim uploadedLocation As String = "\testing\"
System.IO.Directory.CreateDirectory(uploadedTemp)
Dim filePath As String = System.IO.Path.Combine(uploadedTemp, partIndex & Convert.ToString(".tmp"))

If Not System.IO.File.Exists(filePath) Then
    Dim inputStream As System.IO.Stream = request.Files(0).InputStream
    Using fileStream As System.IO.FileStream = System.IO.File.OpenWrite(filePath)
        inputStream.CopyTo(fileStream)
    End Using
End If

'check if we have all parts
If partIndex = (totalParts - 1) Then                
    'merge parts into one file
    mergeTempFiles(uploadedTemp, uploadedLocation, filename)
End If

Public Sub mergeTempFiles(pathOrigin As String, pathToSave As String, filename As String)
    Dim tmpfiles As String() = System.IO.Directory.GetFiles(pathOrigin, "*.tmp")
    If Not System.IO.Directory.Exists(pathToSave) Then
        System.IO.Directory.CreateDirectory(pathToSave)
    End If

    Dim outPutFile As New System.IO.FileStream(pathToSave & filename, System.IO.FileMode.Create, System.IO.FileAccess.Write)

    For Each tempFile As String In tmpfiles
        Dim bytesRead As Integer = 0
        Dim buffer As Byte() = New Byte(1023) {}
        Dim inputTempFile As New System.IO.FileStream(tempFile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Read)

        While (InlineAssignHelper(bytesRead, inputTempFile.Read(buffer, 0, 1024))) > 0
            outPutFile.Write(buffer, 0, bytesRead)
        End While
        inputTempFile.Close()
    Next
    outPutFile.Close()
End Sub

为了防止其他人遇到同样的问题,我找到了解决方案。

事实证明,某些文件类型(例如 PDF)的 .tmp 文件需要按照它们创建时的顺序进行合并。

所以我需要检查是否已收到所有部分,然后遍历它们并复制到我的输出文件。

例如

dim tempFile as string = "" 
using outPutFile as System.IO.FileStream = File.Create(pathToSave & filename) 
     for x as integer = 0 to totalParts-1 
        tempFile = pathOrigin & x & ".tmp" 
        using input as System.IO.FileStream = File.OpenRead(tempFile) 
            input.CopyTo(outPutFile) 
        end using 
        File.Delete(tempFile) 
    Next 
end using