为什么将字符串写入文件,然后将同一个文件作为字符串读取会导致不同的字符串?
Why does writing a string to a file and then reading the same file as a string result in different strings?
我正在尝试编写一些代码来将照片数据保存到文件中。
我读入了照片数据,它是来自 React Native (Expo) 的 base64 字符串,然后我对其进行了解码。我立即将该解码后的字符串写入文件。
当我读取应该包含所有照片数据的文件时,当我期望有很多兆字节的字符时,我得到的只是 4 个字符。
有人知道如何使用 Expo 将这个解码后的 base64 字符串写入文件吗?下面是我的代码...
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
});
你可以看到它非常简单,所以我一定错过了什么?下面是 console.log
...
的输出
Object {
"blahLength": 4,
"equals": false,
"fileUri": "file:///var/mobile/Containers/Data/Application/33EB7A6F-AA1A-42BF-B252-9A5088A906C6/Documents/ExponentExperienceData/%2540anonymous%252FWIB-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/%2540anonymous%252FWIB-mobile-12902e68-9c57-4230-a3df-aaa355c3edf1/20220328184945/1648511392902/Right.jpg.enc",
},
}
您可以看到长度不匹配。另外,如果我打印出 fooString
和 blah
,它们是用于比较的前后字符串,fooString
对我来说看起来是正确的,而且我希望它看起来是正确的,但是 blah
只是 4 个字符的数据。以下是 blah
字符串和文件的不正确内容 ...
我修改了一个现有的小吃来展示我的情况。此小吃提供拍照或 select 现有照片的选项。我将我的代码放在 select 来自照片库处理程序的现有照片中。这个小吃表明,当我将数据写入文件然后将其读回时,数据不匹配。有什么想法吗?
您实际保存的是来自原始文件的原始二进制数据,然后再读回。问题是 writeAsStringAsync
和 readAsStringAsync
在 Expo 上并不真正支持它,因为它不是真正的字符串而是任意二进制数据。
这里有一个错误报告:https://github.com/expo/expo/issues/2453。到目前为止,它已被忽略,唯一的解决方法是保存原始文件的 base64 表示形式。虽然这可行,但它使文件对任何其他程序都无用,增加了 33% 的存储需求,并且在使用前需要特殊解码。
我正在尝试编写一些代码来将照片数据保存到文件中。
我读入了照片数据,它是来自 React Native (Expo) 的 base64 字符串,然后我对其进行了解码。我立即将该解码后的字符串写入文件。
当我读取应该包含所有照片数据的文件时,当我期望有很多兆字节的字符时,我得到的只是 4 个字符。
有人知道如何使用 Expo 将这个解码后的 base64 字符串写入文件吗?下面是我的代码...
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
});
你可以看到它非常简单,所以我一定错过了什么?下面是 console.log
...
Object {
"blahLength": 4,
"equals": false,
"fileUri": "file:///var/mobile/Containers/Data/Application/33EB7A6F-AA1A-42BF-B252-9A5088A906C6/Documents/ExponentExperienceData/%2540anonymous%252FWIB-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/%2540anonymous%252FWIB-mobile-12902e68-9c57-4230-a3df-aaa355c3edf1/20220328184945/1648511392902/Right.jpg.enc",
},
}
您可以看到长度不匹配。另外,如果我打印出 fooString
和 blah
,它们是用于比较的前后字符串,fooString
对我来说看起来是正确的,而且我希望它看起来是正确的,但是 blah
只是 4 个字符的数据。以下是 blah
字符串和文件的不正确内容 ...
我修改了一个现有的小吃来展示我的情况。此小吃提供拍照或 select 现有照片的选项。我将我的代码放在 select 来自照片库处理程序的现有照片中。这个小吃表明,当我将数据写入文件然后将其读回时,数据不匹配。有什么想法吗?
您实际保存的是来自原始文件的原始二进制数据,然后再读回。问题是 writeAsStringAsync
和 readAsStringAsync
在 Expo 上并不真正支持它,因为它不是真正的字符串而是任意二进制数据。
这里有一个错误报告:https://github.com/expo/expo/issues/2453。到目前为止,它已被忽略,唯一的解决方法是保存原始文件的 base64 表示形式。虽然这可行,但它使文件对任何其他程序都无用,增加了 33% 的存储需求,并且在使用前需要特殊解码。