Using Expo.FileSystem to save images to disk, from zip file

I created an example repo of how to download a .zip file & unzip it: https://github.com/smoll/crna-zipfile

This works great for text files, but when I attempt to save an image (as a binarystring), it doesn’t seem to be a valid file. I had to set the uri to a base64 string in order to get the image to display (this code works):

Anyone have any idea how I could correctly save the image file to disk? FileSystem.writeAsStringAsync() only seems to work for text files. Here’s the documentation from JSZip that I was following along with:

@nikki any thoughts here?

Yeah right now the FileSystem API only supports plaintext content of files. One way to do this could be to do a to-from base64 encoding for binary files, or to use the upcoming Blob API. Do you think the base64-based API could work for your use case?

@nikki I think a base64-based approach could work, but can you provide a code example of what that looks like? Is there another function that allows me to read/write base64 encoded images?

Edit: not sure if this is what you meant, but I ended up storing my images in SQLite for now, as base64 string uris, as I alluded to above:

const b64uri = `data:image/jpeg;base64,${base64}`

I was struggling with the same problem when trying to generate Excel files and saving them to the device. I was able to work around the it by using FileSystem.downloadAsync. It’s meant for downloading files from external URLs but seems to work just fine with data URLs.

    FileSystem.downloadAsync(
      `data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,${content}`,
      fileUri,
    )
1 Like

I appreciate the idea on this @kaivosukeltaja, but all my testing of your suggestion results in an “unexpected url” error. I paste the same data URL into my browser and it works fine, so I can confirm that the data URI I’m testing with is properly formatted. I’m using Expo SDK 25. Any further thoughts?

I very much need a solution to this issue and really prefer not to detach. I have created an eReader that downloads zipped epubs, but cannot save any of the binary files to the system after I unzip the epub. My best solution to this point has been to redownload all the binary files directly with downloadAsync, but this takes forever and is not a viable final solution.

Yep, just noticed that it only works on iOS. I’m using the same SDK version and now again looking for a proper solution. A base64 based file save would work for me but I can’t find any information whether that’s currently possible or not.

@nikki, do we have any way to save a Blob to storage?
After fetching the image (I use my own fetch instead of FileSystem.downloadAsync because I have to set the authentication header) I can receive the blob but don’t know how to save to FileSystem.

Could you please help?

Hi @khoacoi - did you figure this out? I am looking at a similar problem… Thanks!

@ldwight Any luck with this? I am also running into the same problem as @khoacoi. Thanks!

Hi @medberg - my problem was slightly different- trying to save a file to a specific folder.
I basically gave up on that, but copy from the cache directory to the Documents directory and store the info in a SQLite db for retrieval.
If this is the kind of thing you are doing, let me know & I’ll share the particulars.
Yrs,
ldwight

Gave up, too :smiley:

Good news! As of version 31, this is easy.

import { FileSystem } from "expo"
import JSZip from "jszip"

// get zipData

const zip = await JSZip.loadAsync(zipData)

// create all necessary dirs

// write unzipped files 
zip.forEach((relativePath, file) => {
  if(file.dir) return

  const uri = `${localBaseUri}${relativePath}`

  file.async('base64').then(base64 => {
    FileSystem.writeAsStringAsync(uri, base64, {
       encoding: FileSystem.EncodingTypes.Base64,
     })
  })
})
1 Like