I have been struggling with this problem for a couple of days: I cannot manage to read a file's content in Android. I have tried this both ways, and in both I have the same results: it never goes further of the file read (execution freezes there), I don't get a result, I don't get an error.
I have tried it with JS FileReader
const dirContent: Entry[] = await this.cordovaFile.listDir(this.file.dataDirectory, 'scans');
for (const entry of dirContent) {
if (entry.isFile) {
(entry as FileEntry).file(file => {
const reader = new FileReader();
reader.onloadend = (data) => console.log('I never get here');
reader.readAsText(file);
console.log('I get here');
});
}
}
And also tried it with Cordova readAsURL
const dirContent: Entry[] = await this.file.listDir(this.file.dataDirectory, 'scans');
for (const entry of dirContent) {
if (entry.isFile) {
const e = entry as FileEntry;
const path = this.file.dataDirectory 'scans'; // d.fileName.substring(0, index);
const index = e.nativeURL.lastIndexOf('/');
const filename = e.nativeURL.substring(index 1);
console.log('I get here');
const contents = await this.file.readAsDataURL(path, filename);
console.log('I never get here');
}
}
On both the same: execution stops without results or error. I assume that the file is found, as I get errors if I make a mistake in the path or filename (on propose). The file of the only file in the directory I is under 500KB, RAM should not be an issue.
By the way, my goal is to pack the files in a zip file using JSZip, so an alternative to reading the contents is also welcome.
CodePudding user response:
It was exhausting and complicated, but I found the solution here: https://github.com/ionic-team/capacitor/issues/1564#issuecomment-538200971. The whole thread is full of proposed solutions, I recommend a detailed read, as the solution that worked for me might not be useful for you.
I finally made a new function as follows:
private async getFileContents(fileEntry: FileEntry): Promise<string> {
return new Promise<string>(resolve => {
fileEntry.file(iFile => {
const fileReader = new FileReader();
const zoneOriginalInstance = (fileReader as any).__zone_symbol__originalInstance;
const reader = zoneOriginalInstance || fileReader;
reader.onloadend = (data) => resolve(data.target._result as string);
reader.readAsDataURL(iFile);
});
});
}
The key is this __zone_symbol__originalInstance
. After ORing this to FileReader
the onloadend
finally triggers with the proper result.