Home > Enterprise >  Why does writing a string to a file and then reading the same file as a string result in different s
Why does writing a string to a file and then reading the same file as a string result in different s

Time:03-30

I'm trying to write some code to save photo data to a file.

I read in the photo data, which comes in as base64 string from react native (Expo), and then I decode it. I immediately write that decoded string to a file.

When I read that file that should contain all of the photo data, all I'm getting back are 4 characters when I expect many megabytes-worth of characters.

Does anybody know how to write this decoded base64 string to a file using Expo? Below is my code ...

  const fileUri = `${directoryPath}/${today.getTime()}/${fileName}`;

  // this reads us the base64 encoded image data
  const imageString = await FileSystem.readAsStringAsync(
    image.uri,
    { encoding: FileSystem.EncodingType.Base64 }
  );

  const fooString = Base64.decode(imageString);

  // write the decoded photo data to a file
  await FileSystem.writeAsStringAsync(fileUri, fooString);

  // read back the file so we can make sure all the data was written
  const blah = await FileSystem.readAsStringAsync(fileUri);

  const photoInfo = await FileSystem.getInfoAsync(fileUri);

  console.log({
    fileUri,
    fooStringLength: fooString.length,
    blahLength: blah.length,
    equals: blah === fooString,
    photoInfo
  });

You can see it's pretty straightforward, so I must be missing something? Below is the output of that console.log ...

Object {
  "blahLength": 4,
  "equals": false,
  "fileUri": "file:///var/mobile/Containers/Data/Application/33EB7A6F-AA1A-42BF-B252-9A5088A906C6/Documents/ExponentExperienceData/%40anonymous%2FWIB-mobile-12902e68-9c57-4230-a3df-aaa355c3edf1/20220328184945/1648511392902/Right.jpg.enc",
  "fooStringLength": 2953317,
  "photoInfo": Object {
    "exists": true,
    "isDirectory": false,
    "modificationTime": 1648511394.334474,
    "size": 4415423,
    "uri": "file:///var/mobile/Containers/Data/Application/33EB7A6F-AA1A-42BF-B252-9A5088A906C6/Documents/ExponentExperienceData/%40anonymous%2FWIB-mobile-12902e68-9c57-4230-a3df-aaa355c3edf1/20220328184945/1648511392902/Right.jpg.enc",
  },
}

You can see the lengths don't match. Also, if I print out both fooString and blah, which are the before and after strings for comparison, the fooString looks correct to me and how I expect it to look but the blah is only like 4 characters worth of data. Below is the incorrect content of blah string and the file ...

enter image description here

I modified an existing snack to show my situation. This snack gives the option to take a photo or select an existing photo. I put my code in the select an existing photo from the photo library handler. This snack shows that when I write my data to a file and then read it back the data does not match. Any ideas why?

https://snack.expo.dev/@rcoleils/camera

CodePudding user response:

What you're actually saving is the raw binary data that comes from the original file, then reading back. Problem is that it isn't really supported on Expo with writeAsStringAsync and readAsStringAsync, as it's not really a string but arbitrary binary data.

There is a bug report on this here: https://github.com/expo/expo/issues/2453. So far it has been ignored with the only workaround of saving the base64 representation of the original. While this could work, it renders the file useless for any other program, increases storage needs by 33% for it and requires special decoding before using.

  • Related