Android开发:openFileInput触发IllegalArgumentException求助
解决Android中openFileInput触发IllegalArgumentException及文件读取问题
嘿,我来帮你揪出代码里的问题!先看你遇到的IllegalArgumentException,这个错误的根源其实是对openFileInput()方法的用法理解错了——这个方法是专门用来读取应用内部存储(private目录)里的文件的,它只接受文件名,不能传完整路径。你把外部存储的完整路径/storage/emulated/0/tut/savedfile.txt传进去,它自然会报错说路径里有分隔符。
你的代码里的核心问题
- 用错读取方法:在
readFromStorage1()里,你已经拿到了外部存储的File对象,却误用了openFileInput()(这是内部存储专用方法); - 循环读取逻辑错误:while循环中两次调用
bufferedReader.readLine(),会导致跳过一行内容; - 潜在的空指针隐患:之前的
NullPointerException大概率是因为openFileInput()返回null(路径错误),你直接赋值给fileInputStream后未判空就操作导致的。
修复方案
1. 替换文件读取方式
读取外部存储文件,直接使用FileInputStream创建实例,不要用openFileInput()。
2. 修正循环读取逻辑
把readLine()的结果存到临时变量中,避免重复调用导致丢行。
3. 优化资源管理
用Java的try-with-resources语法,自动关闭流,不用手动写finally块,更简洁安全。
修改后的readFromStorage1()代码
public String readFromStorage1() { String filePath = getExternalSdCardPath() + "/tut/savedfile.txt"; File file = new File(filePath); // 先判断文件是否存在 if (!file.exists()) { return "Null"; } StringBuilder stringBuilder = new StringBuilder(); // try-with-resources自动关闭所有实现AutoCloseable的资源 try (FileInputStream fileInputStream = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fileInputStream); BufferedReader bufferedReader = new BufferedReader(isr)) { String line; // 一次读取一行,存到临时变量后判断并追加 while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line); } } catch (FileNotFoundException e) { e.printStackTrace(); return "Null"; } catch (IOException e) { e.printStackTrace(); return "Null"; } // 最后判断是否读取到内容 return stringBuilder.length() > 0 ? stringBuilder.toString() : "Null"; }
关于外置SD卡写入的补充
你提到的外置SD卡写入问题,这里也顺带提一下:
- Android 6.0+ 需要动态申请
WRITE_EXTERNAL_STORAGE权限; - Android 10(API 29)+ 启用了分区存储,默认无法直接写入外置SD卡的任意目录,可选方案:
- 使用应用专属的外部存储目录(
getExternalFilesDir()); - 通过**存储访问框架(SAF)**让用户手动选择写入目录;
- 申请
MANAGE_EXTERNAL_STORAGE权限(需用户手动授权,Google Play对该权限有使用限制)。
- 使用应用专属的外部存储目录(
异常原因详解
你看到的异常日志:
java.lang.IllegalArgumentException: File /storage/emulated/0/tut/savedfile.txt contains a path separator
这是因为openFileInput()内部会调用makeFilename()方法,该方法会校验传入的文件名,不允许包含/这类路径分隔符——它默认是在应用内部存储的files目录下查找文件,所以只需要传文件名即可,不能传完整路径。
内容的提问来源于stack exchange,提问作者jobin
相关产品推荐
相关产品推荐

