Android使用Apache POI导出Excel时生成目录而非文件的问题
Android Apache POI导出Excel生成同名目录问题解决方案
核心报错说明
你遇到的Is a directory类型FileNotFoundException,本质是待写入的目标路径已经被一个同名目录占用,FileOutputStream仅支持对普通文件执行写入操作,无法向目录写入内容,因此触发异常。
典型报错日志:
java.io.FileNotFoundException: /storage/emulated/0/Android/data/aa.bb.com.modules.tabbank/files/Download/CollectionReport163548565.xls (Is a directory) at java.io.FileOutputStream.open0(Native Method) at java.io.FileOutputStream.open(FileOutputStream.java:287) at java.io.FileOutputStream.<init>(FileOutputStream.java:223) at java.io.FileOutputStream.<init>(FileOutputStream.java:110)
问题触发原因
- 旧代码残留操作:调试过程中旧版本代码可能误对目标File对象调用了
mkdir()/mkdirs()方法,直接生成了和.xls文件同名的目录,后续修改代码后未清理应用残留文件,旧目录一直存在就会持续触发报错。 - adb同步异常:Linux环境下adb与Android设备的文件同步偶尔会出现缓存错乱,或是调试过程中误操作在对应下载目录下创建了同名目录,应用无权限删除非自身生成的目录就会一直报错。
- 路径拼接不规范:直接字符串拼接文件路径可能出现多余分隔符,导致系统识别路径时将.xls后缀判定为目录名的一部分,误生成目录。
优化修复方案
代码优化(永久解决)
操作文件前增加状态校验逻辑,避免残留文件影响,同时优化路径拼接方式,代码示例如下:
// 优先通过File构造方法拼接路径,避免字符串拼接的分隔符错误 File parentDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS); // 父目录不存在时先创建父目录,不要对目标文件调用mkdirs if (!parentDir.exists()) { parentDir.mkdirs(); } File excelFile = new File(parentDir, fileName); // 如果目标路径已存在且是目录,先删除残留目录 if (excelFile.exists() && excelFile.isDirectory()) { excelFile.delete(); } FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(excelFile); workbook.write(fileOutputStream); Log.e(TAG, "Writing file succeeded: " + excelFile.getAbsolutePath()); isSuccess = true; } catch (IOException e) { Log.e(TAG, "Error writing file: ", e); isSuccess = false; } catch (Exception e) { Log.e(TAG, "Save file failed: ", e); isSuccess = false; } finally { // 主动关闭输出流,避免资源泄漏 if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } }
临时修复
调试过程中出现的偶发该问题,直接卸载应用清理所有残留文件后重装即可解决,你遇到的重启开发电脑、重装应用后恢复正常,本质就是重装时清理了之前残留的同名目录。
内容的提问来源于stack exchange,提问作者Rajendra Shrestha
相关产品推荐
相关产品推荐

