-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support encodings other than UTF-8 (and binary) #31
Comments
Lowering the priority on this now. I realized that even Cordova only supports UTF-8. Any other encoding is probably quite rare these days. |
Is there any way we can get this to store binary files that are obtained by HTTP as blob objects? |
Just tried to write a binary file and the current documentation is misleading: This should be the same as in Also, passing an invalid base64 string to @geferon You can use the FileReader class of the standard JavaScript File API to read the contents of a Blob. |
But I don't want to read, I want to WRITE binary files into the filesystem with obtained blobs from an HTTP request. |
I have a similar requirement to @geferon except that I need to download fairly large videos to the filesystem. I feel uncomfortable about passing these around as strings. Despite the deprecation notice on cordova-plugin-file-transfer, it looks like it will do the job. For storing arbitrary Blobs on the filesystem, looks like cordova-plugin-file might be the way to go. |
@diachedelic That's exactly what I'm doing right now but it'd be nice if we had native Capacitor support instead of having to use a Cordova plugin |
So am I correct in saying that Capacitor cannot write binary files downloaded via HTTP to the filesystem? |
Here's the code I'm using to write a binary blob to the file system: readAsBinaryString(file: Blob): Promise<string> {
return new Promise((resolve, reject) => {
var reader = new FileReader();
reader.onloadend = (event) => {
resolve(reader.result as string);
};
reader.onerror = (event) => {
reject(reader.error);
};
reader.readAsBinaryString(file);
});
}
async save(blob: Blob, filename: string): void {
try {
let binaryString = await this.readAsBinaryString(blob);
let base64String = btoa(binaryString);
await Filesystem.writeFile({
data: base64String,
directory: FilesystemDirectory.Cache,
path: filename
});
} catch (error) {
console.error(error);
}
} |
Thanks @sttz! |
It's good that there's workaround using base64, but I'm wondering what's the memory impact of converting to a data string? I remember that passing with base64 strings to Cordova often resulted in crashes. |
@jairemix it has caused crashes for me with files several megabytes or larger, which is why we write the file incrementally (see https://gist.github.com/diachedelic/9aa3790e045e37327bffdcfaadd29253). It is a shame that there does not seem to be any way that native code can directly read binary data from inside the webview - all data crossing the "bridge" must be strings. |
For our game engine Construct (which has Cordova-based mobile publishing), it is important to have the capability to read binary files, so it would be good if the Capacitor APIs could be updated to cover that. FWIW, cordova-plugin-file has some really terrible pitfalls. Significantly, it replaces the global |
How is this a low priority? |
Going to close since this is going off-topic and and most requests have nothing to do with the title. I think utf-8 and binary are enough and the cordova plugin only offers that. As it has been mentioned, everything that goes through the bridge has to be a string, so it's not possible to pass a Blob or File. So, if you need to download very big files, better use a native plugin that does the download and write by just passing the url string to it, that way there is no bridge limitation. If it's not that big, use the FileReader or another of the proposed solutions. For reading files, apart from Filesystem plugin, you can also use |
Our use case is we need to read a binary file from the app package, e.g. a PNG image. Currently the only option is to use cordova-plugin-file which does appalling things to compatibility, as I described, and we're desperate to get rid of it. I don't see any other workarounds. We can't do something like convert to base64, because the image file is already in a binary format and needs to be read as binary. There's a great opportunity for Capacitor to fix a huge pain point of Cordova here. Please reconsider! For example it could provide a method to read a binary file, internally do any base64 conversion to get it across a text bridge, and then return a File object to JS. |
As I said, that's a separate issue from the one reported here, the issue went off-topic and you all reported different things. And, as I said, using fetch/xhr with a converted url to the file path (if it's in the public folder you don't even need to convert, just use the relative url), you can get the image Blob with no plugins involved. |
There is an issue about the blob/large files read/write #984 |
Fetch doesn't work on the file: protocol. Browser vendors are basically trying to phase it out. |
That’s why you have to use Capacitor.convertFileSrc on the file url, and/or use an absolute path if the file is in public folder. |
@jcesarmobile this running the |
@seanharr11 possibly related to #2882? that usage works fine for me. |
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out. |
For filesystem API
The text was updated successfully, but these errors were encountered: