Когда я пытаюсь загрузить большой файл с помощью 3 новых методов (StartUpload, ContinueUpload, FinishUpload), загружая фрагменты файла, то окончательный загруженный файл является поврежденным файлом, и размер также больше, чем фактический файл. Я использовал Rest API для загрузки больших файлов.
Выполняются следующие шаги: -
- Создайте HTML для входного файла.
<input name="FileUpload" type="file" id="uploadInput" className="inputFile" multiple="false" onchange="upload(this.files[0])" />
Ниже приведен метод начальной точки кода:
- Creating Global variable for siteurl
var Tasks = {
urlName: window.location.origin + "/",
siteName: '/sites/ABC',
};
Вызов метода Upload ()
Сначала создайте фиктивный файл размером 0 в папке, чтобы продолжить загрузку большого файла.
Создайте объект FileReader, а затем начните создавать фрагменты файла с 3 параметрами (смещение, длина, метод (например, start / continue / finishupload)) и вставьте фрагменты в массив.
- Создание уникального идентификатора для загрузки, например, uploadID
- Вызов метода UploadFile
function upload(file) {
var docLibraryName = "/sites/ABC/Shared Documents";
var fileName = $("#uploadInput").val().replace(/C:\\fakepath\\/i, '');
var folderName = "";
createDummaryFile(docLibraryName, fileName, folderName)
var fr = new FileReader();
var offset = 0;
var total = file.size;
var length = 1000000 > total ? total : 1000000;
var chunks = [];
fr.onload = evt => {
while (offset < total) {
if (offset + length > total)
length = total - offset;
chunks.push({
offset,
length,
method: getUploadMethod(offset, length, total)
});
offset += length;
}
for (var i = 0; i < chunks.length; i++)
console.log(chunks[i]);
if (chunks.length > 0) {
const id = getGuid();
uploadFile(evt.target.result, id, docLibraryName, fileName, chunks, 0);
}
};
fr.readAsArrayBuffer(file);
}
function createDummaryFile(libraryName, fileName, folderName) {
return new Promise((resolve, reject) => {
var endpoint = Tasks.urlName + Tasks.siteName + "/_api/web/GetFolderByServerRelativeUrl('" + libraryName + "/" + folderName + "')/Files/add(url=@TargetFileName,overwrite='true')?" +
"&@TargetFileName='" + fileName + "'";
var url;
const headers = {
"accept": "application/json;odata=verbose"
};
performUpload(endpoint, headers, libraryName, fileName, folderName, convertDataBinaryString(0));
});
}
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
function getGuid() {
return (S4() + S4() + "-" + S4() + "-4" + S4().substr(0, 3) + "-" + S4() + "-" + S4() + S4() + S4()).toLowerCase();
}
//check position for selecting method
function getUploadMethod(offset, length, total) {
if (offset + length + 1 > total) {
return 'finishupload';
} else if (offset === 0) {
return 'startupload';
} else if (offset < total) {
return 'continueupload';
}
return null;
}
Метод загрузки файла
Преобразуйте буфер массива в блоки больших двоичных объектов, чтобы начать загрузку файла
Начните фактическую загрузку фрагментов файлов, используя методы и смещение в 1 МБ, которые мы создали ранее (метод uploadFileChunk)
Запустить цикл для фрагмента и вызвать тот же метод
function uploadFile(result, id, libraryPath, fileName, chunks, index) {
const data = convertFileToBlobChunks(result, chunks[index]);
var response = uploadFileChunk(id, libraryPath, fileName, chunks[index], data);
index += 1;
if (index < chunks.length)
uploadFile(result, id, libraryPath, fileName, chunks, index, chunks[index].offset);
}
function convertFileToBlobChunks(result, chunkInfo) {
var arrayBuffer = chunkInfo.method === 'finishupload' ? result.slice(chunkInfo.offset) : result.slice(chunkInfo.offset, chunkInfo.offset + chunkInfo.length);
return convertDataBinaryString(arrayBuffer);
}
function convertDataBinaryString(data) {
var fileData = '';
var byteArray = new Uint8Array(data);
for (var i = 0; i < byteArray.byteLength; i++) {
fileData += String.fromCharCode(byteArray[i]);
}
return fileData;
}
UploadFileChunk, чтобы начать загрузку фрагментов файлов)
- Form string if startupload then no fileoffset and if continueupload and finishupload then it will have fileoffset.
- Вызов метода performupload, чтобы начать загрузку с использованием rest api
function uploadFileChunk(id, libraryPath, fileName, chunk, data) {
new Promise((resolve, reject) => {
var offset = chunk.offset === 0 ? '' : ',fileOffset=' + chunk.offset;
var folderName = "";
var endpoint = Tasks.urlName + Tasks.siteName + "/_api/web/getfilebyserverrelativeurl('" + libraryPath + "/" + fileName + "')/" + chunk.method + "(uploadId=guid'" + id + "'" + offset + ")";
const headers = {
"Accept": "application/json; odata=verbose",
"Content-Type": "application/octet-stream"
};
performUpload(endpoint, headers, libraryPath, fileName, folderName, data);
});
}
function performUpload(endpoint, headers, libraryName, fileName, folderName, fileData) {
new Promise((resolve, reject) => {
var digest = $("#__REQUESTDIGEST").val();
$.ajax({
url: endpoint,
async: false,
method: "POST",
headers: headers,
data: fileData,
binaryStringRequestBody: true,
success: function(data) {},
error: err => reject(err.responseText)
});
});
}
Пожалуйста, подскажите, почему загруженный файл поврежден и имеет размер меньше или больше фактического?
Заранее спасибо.