Android 14下使用react-native-blob-util写入流时出现ENOENT错误
Android 14下react-native-blob-util写入DownloadDir失败问题
问题背景
使用react-native-blob-util的流写入代码,原本在Android 14运行正常,为适配Android 9添加运行时权限后,Android 14出现ENOENT错误,无法创建并写入文件到公共Download目录。
原代码
let {dirs} = ReactNativeBlobUtil.fs; const dirToSave = Platform.OS == 'ios' ? dirs.DocumentDir : dirs.DownloadDir; let PATH_TO_FILE = dirs.DownloadDir + '/' + json.fileName.replace(/ /g, '') + '.pdf'; ReactNativeBlobUtil.fs.writeStream( PATH_TO_FILE, 'base64', true ) .then(stream => Promise.all([ stream.write(json.fileContent) ])) .then(([stream]) => { stream.close() ToastAndroid.show('File saved in downloads', ToastAndroid.LONG) }) .catch(console.error)
错误信息
{ [Error: File '/storage/emulated/0/Download/sTitleENFinal.pdf' does not exist and could not be created] code: 'ENOENT', line: 106879, column: 30, sourceURL: 'http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.package.name&modulesOnly=false&runModule=true' }
解决方案
1. 适配Android 14存储权限规则
Android 14对公共目录(如Download)的写入权限做了严格限制,直接写入会触发权限拦截,可选择两种方案:
方案A:改用应用私有存储目录
应用私有目录无需额外权限,且不受Android版本存储规则限制,修改代码如下:
let {dirs} = ReactNativeBlobUtil.fs; // Android端改用应用私有文档目录 const dirToSave = Platform.OS === 'ios' ? dirs.DocumentDir : dirs.DocumentDir; let PATH_TO_FILE = dirToSave + '/' + json.fileName.replace(/ /g, '') + '.pdf'; ReactNativeBlobUtil.fs.writeStream( PATH_TO_FILE, 'base64', true ) .then(stream => stream.write(json.fileContent).then(() => stream)) .then(stream => { stream.close(); ToastAndroid.show('文件已保存到应用私有目录', ToastAndroid.LONG); }) .catch(console.error);
方案B:适配公共目录写入权限(需审核)
若必须写入公共DownloadDir,需做以下配置:
- 在
AndroidManifest.xml中添加权限声明:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> - 动态申请权限:Android 13+申请
READ_MEDIA_*权限,Android 12及以下申请WRITE_EXTERNAL_STORAGE权限。 - 更新react-native-blob-util到最新版本,确保库已适配Android 14的MediaStore写入逻辑。
2. 修复代码冗余逻辑
原代码中Promise.all([stream.write(json.fileContent)])属于冗余写法,直接返回stream.write的Promise即可,避免解构错误:
.then(stream => { return stream.write(json.fileContent).then(() => stream); }) .then(stream => { stream.close(); ToastAndroid.show('File saved in downloads', ToastAndroid.LONG); })
3. 更新依赖版本
确保使用最新版react-native-blob-util,旧版本可能未适配Android 14存储变更:
npm install react-native-blob-util@latest
内容的提问来源于stack exchange,提问作者Zubair Akber
相关产品推荐
相关产品推荐

