I am working on a backup system with Google Drive v3 REST API. I upload a sqlite backup file to a folder on Google Drive. That works. I am able to upload and list the files in the folder.
So now I am working on restoring that file in my application. But when I download the file and write the response stream I end up with a corrupted db file. When I open it up in notepad I see that any special characters such as ^ etc are all squares and the file is like 2 mb bigger than what was uploaded.
I have been at this for two days now and cannot figure out why the file is not writing 1:1 copy of what is downloaded
this is my current code for the download ..
async restoreGoogleDriveDatabase(fileId){
const url = encodeURI(`https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`);
const options = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' this.getToken()
},
}
await fetch(url, options).then(async response => response.text())
.then(arrayBuffer => {
const path = require('path').join(window.process.env.ProgramData, 'Home Inventory');
fs.writeFile(`${path}\\HomeInventory1.db`, arrayBuffer, function () {
console.warn('file created');
});
});
},
Looking for any kind of help that would get me back on the right track.
CodePudding user response:
The issue seems to be with character encoding
The simplest fix is to fetch the result as an arrayBuffer, and write out the arrayBuffer using "binary" encoding
Like so
const fs = require('node:fs/promises');
async restoreGoogleDriveDatabase(fileId) {
const url = encodeURI(`https://www.googleapis.com/drive/v3/files/${fileId}?alt=media`);
const options = {
method: 'GET',
headers: {
'Authorization': 'Bearer ' this.getToken()
},
}
try {
const response = await fetch(url, options);
const arrayBuffer = await response.arrayBuffer();
const path = require('path').join(window.process.env.ProgramData, 'Home Inventory');
await fs.writeFile(`${path}/HomeInventory1.db`, Buffer.from(arrayBuffer, "binary"));
console.warn('file created');
} catch (err) {
console.error(err);
}
},
The code above uses async/await correctly, and also uses fs/promises
instead of fs
, since already using async/await
it makes sense to use the Promise version of fs
methods
The important changes are
response.arrayBuffer()
To get the response as an arrayBuffer
and in fs.writeFile
use
Buffer.from(arrayBuffer, "binary")
To write the data "as-is" to the file