如何在 Android 中正确写入 JSON 文件

落宇酱_7189

落宇酱_7189

2026-05-29

574人浏览

原创

如何在 Android 中正确写入 JSON 文件

本文详解 android 应用中向内部存储写入 json 文件的正确方法,指出常见错误(如路径误用、流未刷新、权限与模式混淆),并提供基于 gson 的稳定、可复用的实现方案。

本文详解 android 应用中向内部存储写入 json 文件的正确方法,指出常见错误(如路径误用、流未刷新、权限与模式混淆),并提供基于 gson 的稳定、可复用的实现方案。

在 Android 中将数据序列化为 JSON 并持久化到文件,看似简单,却极易因环境差异(如文件系统权限、上下文作用域、流管理)导致“静默失败”——无异常抛出,但文件内容未更新。你提供的三段尝试均存在关键问题,下面逐一解析并给出工业级可靠写法。

❌ 常见错误分析

  • Method 1(gson.toJson(..., new FileWriter(file))):
    FileWriter 默认使用平台默认编码(可能非 UTF-8),且 FileWriter 不适用于 Android 内部私有目录的健壮写入;更严重的是,FileWriter 不保证立即刷盘,且未显式调用 flush() 或 close()(虽 gson.toJson 内部会关闭,但异常路径下易遗漏)。

  • Method 2(openFileOutput(path, ...)):
    openFileOutput() 仅接受文件名(如 "test.json"),不接受完整路径。传入绝对路径(如 /data/data/.../test.json)会导致 FileNotFoundException 或静默失败——这是最隐蔽的坑!

  • Method 3(new FileWriter(file) 直接写字符串):
    同样绕过 Android 文件系统安全模型;若 file 所在目录不存在(如子目录嵌套),FileWriter 不会自动创建父目录,直接抛 IOException(但你 catch 了却未 log,导致“看不见的错误”)。

  • 额外陷阱:file.setWritable(true) 在 Android 10+(Scoped Storage)及内部私有目录中完全无效且多余——getFilesDir() 返回的路径天然可写,调用该方法无实际作用。

    Android Remote Control
    Android Remote Control

    远程控制 Android 设备,支持截图、自动化操作手机 App 等功能。本应用使用 uiautomator2 作为底层框架,通过 ADB 连接设备,用户无需 Root(1)查看手机屏幕;(2)自动化操作手机 App;(3)远程安装/卸载应用……

    下载

✅ 正确写法:安全、可靠、可扩展

以下代码是经过验证的生产就绪方案,使用 FileOutputStream + Gson,兼顾编码控制、目录创建、异常反馈与资源安全释放:

private void writeJsonToFile(Object data, String fileName) {
    File file = new File(getFilesDir(), fileName); // ✅ 正确:仅传文件名,根目录由 getFilesDir() 提供
    try {
        // 确保父目录存在(尤其当 fileName 含子目录时,如 "data/player.json")
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        if (!file.exists()) {
            file.createNewFile(); // ✅ 显式创建文件(避免 FileNotFoundException)
        }

        // 使用 UTF-8 编码写入 JSON 字符串
        String json = new Gson().toJson(data);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(json.getBytes(StandardCharsets.UTF_8)); // ✅ 明确指定 UTF-8
        fos.flush(); // ✅ 强制刷入磁盘
        fos.close();

        Log.d("JSON_WRITE", "Success: " + file.getAbsolutePath());
        Toast.makeText(this, "Saved to " + fileName, Toast.LENGTH_SHORT).show();

    } catch (IOException e) {
        Log.e("JSON_WRITE", "Failed to write JSON", e);
        Toast.makeText(this, "Save failed: " + e.getMessage(), Toast.LENGTH_LONG).show();
    }
}

调用示例:

// 写入字符串
writeJsonToFile("gjsanhfhj", "test.json");

// 写入对象(推荐)
PlayerData player = new PlayerData();
player.gold = 100;
player.wins = 5;
writeJsonToFile(player, "player.json");

? 关键要点总结

  • ✅ 永远用 getFilesDir() 作为根目录,再拼接文件名(而非 getAbsolutePath() + 手动拼路径);
  • ✅ openFileOutput() 只接收纯文件名,不可传路径;若需路径操作,请统一使用 FileOutputStream;
  • ✅ 必须处理 getParentFile().mkdirs() 和 createNewFile(),避免因目录缺失导致失败;
  • ✅ 显式指定 StandardCharsets.UTF_8,防止中文乱码;
  • ✅ 调用 flush() + close()(或使用 try-with-resources)确保数据落盘;
  • ✅ 添加 Log 和用户反馈(Toast),让“静默失败”变为“可见问题”。

遵循以上实践,即可彻底解决 Android JSON 文件写入失效问题,让数据持久化真正可靠、可调试、可维护。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

2023.06.20

4436

8

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.28

1355

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1758

5

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

2023.08.17

9983

11

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

2023.09.01

980

4

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2764

5

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.14

1569

5

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

2023.09.21

4729

3

js生成随机数方法
js生成随机数方法

JavaScript生成随机数的方法,包括使用Math.random()方法生成指定范围内的随机整数、生成随机字符串和生成随机颜色。根据具体需求,可以选择适合的方法来生成随机数,以实现各种功能 。

2023.09.25

2735

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 44.6万人学习

Java 教程
Java 教程

共578课时 | 193.1万人学习

Uniapp从零开始实现新闻资讯应用
Uniapp从零开始实现新闻资讯应用

共64课时 | 9.6万人学习