当前位置:首页 > 行业动态 > 正文

安卓往存储写文件工作流程

安卓写入存储流程:申请权限→获取存储路径→创建文件输出流→写入数据→关闭流,需处理运行时权限及Android

安卓往存储写文件工作流程


权限检查

  • Android 9及以下:需在AndroidManifest.xml中声明WRITE_EXTERNAL_STORAGE权限,并在运行时动态申请(Android 6.0+)。
  • Android 10+:引入“分区存储”(Scoped Storage),外部存储分为“应用私有目录”和“公共目录”。
    • 写入应用私有目录(如getExternalFilesDir())无需额外权限。
    • 写入公共目录(如Environment.getExternalStoragePublicDirectory())需通过Storage Access FrameworkMediaStore API。

确定存储位置

存储类型 路径示例 适用场景
内部存储 /data/data/包名/files/ 应用私有数据,无需申请权限
外部存储(私有) /storage/emulated/0/Android/data/包名/ Android 10+自动分配,无需权限
外部存储(公共) /storage/emulated/0/Download/ 需用户授权或SAF,Android 10+受限
缓存目录 /data/data/包名/cache/ 临时文件,可被系统清理

创建文件或目录

// 示例:在外部存储私有目录创建文件
File dir = new File(context.getExternalFilesDir(null), "MyApp");
if (!dir.exists()) {
    dir.mkdirs(); // 递归创建目录
}
File file = new File(dir, "data.txt");
  • 注意事项
    • 文件名需合法,避免特殊字符(如、)。
    • 通过file.exists()检查是否已存在,避免覆盖。

写入数据

try (FileOutputStream fos = new FileOutputStream(file)) {
    String data = "Hello World";
    fos.write(data.getBytes()); // 写入字节数组
    fos.flush(); // 确保数据写入磁盘
} catch (IOException e) {
    e.printStackTrace();
}
  • 优化建议
    • 大文件可使用BufferedOutputStream提高写入效率。
    • 二进制文件需按特定格式编码(如图片、音频)。

异常处理与资源释放

  • 常见异常
    • FileNotFoundException:路径不存在或无权限。
    • IOException:存储空间不足或SD卡被移除。
  • 资源释放
    • 使用try-with-resources自动关闭流,避免内存泄漏。
    • Android 10+需处理ScopedAccessFailedException(公共目录访问失败)。

兼容性处理(Android 10+)

  • 替代方案
    • Storage Access Framework:通过Intent.ACTION_CREATE_DOCUMENT让用户选择保存位置。
    • MediaStore API:写入媒体文件(图片、视频)到公共目录。
  • 示例
    // 使用MediaStore保存图片
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.DISPLAY_NAME, "photo.jpg");
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    try (OutputStream os = context.getContentResolver().openOutputStream(uri)) {
      // 写入图片数据
    }

相关问题与解答

问题1:如何在Android 10+中兼容写入外部存储?

解答

  • 应用私有目录:直接使用getExternalFilesDir(),无需权限。
  • 公共目录
    • 使用Storage Access Framework(SAF)让用户选择目录。
    • 通过MediaStore API写入媒体文件。
    • 避免直接使用Environment.getExternalStoragePublicDirectory(),会导致ScopedAccessFailedException

问题2:写入大文件时如何避免内存溢出(OOM)?

解答

  • 分块写入:将大文件拆分为小块,逐块写入磁盘。
  • 使用缓冲流:例如BufferedOutputStream减少I/O次数。
  • 异步处理:在子线程中执行写入操作,避免阻塞主线程。
  • 示例代码
    try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) {
      byte[] buffer = new byte[8192]; // 8KB缓冲区
      int len;
      while ((len = inputStream.read(buffer)) != -1) {
          bos.write(buffer, 0, len);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
0