使用expo-file-system进行Base64读写时的异常行为是否符合预期?
这个行为其实是符合Base64编码规范和expo-file-system的API设计逻辑的,并不是异常情况哦!咱们来拆解你观察到的三种场景,搞清楚背后的原因:
当字符串长度是4的倍数时
此时你传入的字符串刚好符合合法Base64格式的要求(Base64编码后的字符串长度必然是4的倍数)。当writeAsStringAsync使用base64编码选项时,会把这个合法的Base64字符串解码为二进制数据写入文件;读取时readAsStringAsync又将二进制数据重新编码为Base64字符串,自然能和原字符串完全一致。当长度模4等于1时
这种情况下,传入的字符串完全不符合Base64的结构规则——Base64编码后的字符串长度只能是4的倍数,或者余2、余3(此时需要用=填充到4的倍数)。长度模4等于1的字符串属于无效的Base64格式,所以writeAsStringAsync直接抛出解码错误,这是合理的参数校验行为。当长度模4等于2或3时
这里本质是你传入的是不完整的Base64片段,expo-file-system的底层解码逻辑会尝试容错处理(比如自动补全填充符),但这个过程会导致原始数据被篡改。举个例子,你传入"01"(长度模4余2),底层会将其当作"01=="来解码,解码后的二进制数据再编码回Base64就变成了"0w==",所以看起来像是最后字符被“损坏”了——核心问题是你误将普通字符串直接当作合法Base64字符串来写入,才引发了这个结果。
正确的用法提示
你可能搞反了API的用法逻辑!如果你的需求是把普通字符串编码成Base64后存储,正确的做法应该是先将字符串转换为Base64编码的字符串,再以普通文本形式写入:
import { documentDirectory, readAsStringAsync, writeAsStringAsync } from "expo-file-system"; async function correctBase64Handling(s: string) { // 将普通字符串编码为Base64(兼容中文等非ASCII字符) const base64Encoded = btoa(unescape(encodeURIComponent(s))); // 以默认utf8编码写入Base64字符串 await writeAsStringAsync(documentDirectory + "temp.bin", base64Encoded); // 读取时先获取Base64字符串,再解码回原字符串 const readBase64 = await readAsStringAsync(documentDirectory + "temp.bin"); const originalStr = decodeURIComponent(escape(atob(readBase64))); console.log("原字符串:", s); console.log("解码后字符串:", originalStr); }
备注:内容来源于stack exchange,提问作者Jeon

