Я совершенно неопытен со сжатием файлов и API Google Drive.В моем проекте я использую zip.js и Google Drive Api.Zip.js работает хорошо, потому что я загружаю напрямую сгенерированный zip-файл, и мое устройство может распаковать его.Даже если я не добавляю никаких дополнительных данных к содержимому zip-файла, размер zip-файла изменяется (удваивается) и повреждается при его обновлении.
Моя функция для создания zip-файла:
function createZip(data,fileName,callback){
var blob = new Blob([ data ], {
type : "text/xml"
});
zipBlob(fileName, blob, function(zippedBlob){
console.log(zippedBlob)
// saveAs(zippedBlob,"test.zip") //this test.zip is a valid file.
var reader = new FileReader();
reader.addEventListener("loadend", function() {
// reader.result contains the contents of blob as a typed array
console.log(reader.result);
callback(reader.result);
});
reader.readAsText(zippedBlob)
})
function zipBlob(filename, blob, callback) {
zip.createWriter(new zip.BlobWriter("application/zip"), function(zipWriter) {
zipWriter.add(filename, new zip.BlobReader(blob), function() {
zipWriter.close(callback);
});
}, function(error){
console.error(error)
});
}
}
Моя функция обновления файла:
this.updateFile = function(id, text, accessToken, callback) {
var boundary = '-------314159265358979323846',
delimiter = "\r\n--" + boundary + "\r\n",
close_delim = "\r\n--" + boundary + "--",
mimeType = 'application/zip';
var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
delimiter + 'Content-Type:' + mimeType + '\r\n\r\n' +
text +
close_delim;
gapi.client.request({
'path': '/upload/drive/v3/files/'+id,
'method': 'PATCH',
'params': { 'uploadType': 'multipart' },
'headers': { 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"', 'Authorization': 'Bearer ' + accessToken, },
'body': multipartRequestBody
}).execute(function(file) {
if (typeof callback === "function") callback(file);
}, function(error) {
console.error(error)
callback(error);
});
}
Интересно, не повреждает ли FileReader содержимое, потому что reader.result
отличается от исходного содержимого zip.Я использую эту функцию для чтения содержимого файла:
this.readFile = function(fileId, callback) {
var request = gapi.client.drive.files.get({
fileId: fileId,
alt: 'media',
Range : 'bytes=100-200'
})
request.then(function(response) {
console.log(response);
if (typeof callback === "function") callback(response.body);
}, function(error) {
console.error(error)
})
//return request;
}
Исходное содержимое zip в виде текста:
PKÊL PV-A2.xmlUXñçûZÂÌZùì½m,I÷]þC£?I@ÌNøK¼=F °KÃ(«Ýgz=Crçß+²ne§y¸¥U6... (some thousands characters more)
Содержимое программы чтения файлов в виде текста:
PK�U�L PV-A2.xml�]�<��w�O1�+(���� �@�6`@+ �Ґ`��r��EÑ�������̊s"���0�..(some thousands characters more)
РЕШЕНИЕ
Получить данные base64 из zip-файла (не забудьте вырезать data:application/zip;base64,
out):
// saveAs(zippedBlob,"test.zip") //this test.zip is a valid file.
var reader = new FileReader();
reader.addEventListener("loadend", function() {
// reader.result contains the contents of blob as a typed array
callback(reader.result.replace("data:application/zip;base64,",""));
});
reader.readAsDataURL(zippedBlob)
Добавить Content-Transfer-Encoding: base64
в multipartRequestBody и использоватьсодержимое base64.
var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
delimiter + 'Content-Type:' + mimeType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n\r\n' +
base64Data +
close_delim;