Android保存图片到外部存储子目录时触发FileNotFound异常
Android 截图保存到多层子目录时报EISDIR异常
问题相关代码
private fun takeScreenshot() { val now = Date() val formattedTimestamp = DateFormat.format("yyyy-MM-dd_hh:mm:ss", now) try { // 直接存外部存储根目录:运行正常 //val mPath : String = Environment.getExternalStorageDirectory().toString() + "/" + formattedTimestamp + ".jpg" // 存多层自定义子目录:抛出异常 val mPath: String = Environment.getExternalStorageDirectory().toString() + "/mobile/" + GetSetContext.getApplicationName() + "/Screenshots/" + formattedTimestamp + ".jpg" val v = this.view!! v.setDrawingCacheEnabled(true) v.buildDrawingCache(true) val bitmap: Bitmap = Bitmap.createBitmap(v.getDrawingCache()) v.setDrawingCacheEnabled(false) val imageFile = File(mPath) val outputStream = FileOutputStream(imageFile) val quality = 100 bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream) outputStream.flush() outputStream.close() ScreenshotUploadWorkManager().setupUploadingRequest(context, applicationConfiguration,mPath) } }
异常信息
java.io.FileNotFoundException: /storage/emulated/0/mobile/App/Screenshots/2022-06-20_09:00:18.jpg: open failed: EISDIR (Is a directory)
已通过Android Studio Device File Explorer手动创建路径对应所有子目录,问题仍复现。
问题原因与修复方案
- 报错
EISDIR (Is a directory)的直接原因:你要写入的目标路径2022-06-20_09:00:18.jpg实际是个同名目录,不是文件。大概率是你手动创建目录的时候,误把最后一级的jpg文件名也建成了文件夹,直接去Device File Explorer里进入Screenshots目录,找到这个和截图同名的.jpg后缀文件夹删掉即可。 - 代码存在逻辑疏漏:绝对不能依赖手动创建目录,App运行时必须主动校验、递归创建父目录,否则换设备、清存储、改路径都会触发路径不存在的问题。在创建
FileOutputStream之前加入如下逻辑:
val imageFile = File(mPath) // 递归创建所有不存在的父目录 imageFile.parentFile?.takeIf { !it.exists() }?.mkdirs() // 兜底处理:如果目标路径已存在且是目录,先删除错误的目录项 if (imageFile.exists() && imageFile.isDirectory) { imageFile.delete() } val outputStream = FileOutputStream(imageFile)
- 版本适配遗漏:如果你的App targetSdkVersion >= 29(对应Android 10及以上),系统默认开启分区存储,直接访问外部存储公共根目录会被权限拦截。要么在AndroidManifest的
<application>标签下加android:requestLegacyExternalStorage="true"临时兼容,要么改用App私有存储目录、MediaStore API来保存截图,避免权限问题。 - 额外注意:你拼接路径时用的时间戳格式里带冒号
:,部分安卓版本对存储文件的文件名有特殊字符限制,建议把时间格式里的冒号改成下划线,比如yyyy-MM-dd_hh_mm_ss,避免其他机型上出现文件名非法的问题。
内容的提问来源于stack exchange,提问作者Mithun Wijethunga
相关产品推荐
相关产品推荐

