You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何将ArrayList<String>保存到外部存储.txt文件?解决乱码

问题原因分析

你生成的.txt文件出现乱码,核心原因是使用了ObjectOutputStream进行对象序列化写入——这是一种二进制序列化机制,写入的内容包含Java对象的元数据、序列化标记等二进制信息,并非纯文本格式,所以用文本编辑器打开会显示乱码。

另外代码还有两个关键问题:

  • 权限申请错误:写入外部存储需要WRITE_EXTERNAL_STORAGE权限(安卓10及以下),你只申请了READ_EXTERNAL_STORAGE,会导致写入失败。
  • 权限申请是异步操作:调用requestPermissions后不会立即获得权限,直接执行后续写入逻辑会因权限未通过而失败。
修复方案

1. 改用纯文本写入方式

遍历ArrayList<String>,将每个字符串按纯文本格式写入文件,指定UTF-8编码保证字符正确:

void writeTextToFile(Context context, ArrayList<String> arrayList) {
    File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    File file = new File(folder, "file01.txt");

    try (FileWriter writer = new FileWriter(file, StandardCharsets.UTF_8)) {
        for (String str : arrayList) {
            writer.write(str);
            writer.write(System.lineSeparator()); // 每个字符串换行,可选
        }
        Toast.makeText(context, "保存成功", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show();
    }
}

2. 正确处理存储权限

安卓X及以下(API < 30)

需要申请WRITE_EXTERNAL_STORAGE权限,并且在权限回调后执行写入逻辑:

首先在AndroidManifest.xml添加权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

然后在Activity中处理权限申请:

private static final int STORAGE_PERMISSION_CODE = 100;

// 点击按钮时先检查权限
public void onSaveButtonClick(View view) {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                STORAGE_PERMISSION_CODE);
    } else {
        // 权限已通过,执行写入
        writeTextToFile(getApplicationContext(), arrayList);
    }
}

// 权限回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == STORAGE_PERMISSION_CODE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            writeTextToFile(getApplicationContext(), arrayList);
        } else {
            Toast.makeText(this, "需要存储权限才能保存文件", Toast.LENGTH_SHORT).show();
        }
    }
}

安卓10+(API >= 30)

Environment.getExternalStoragePublicDirectory已被废弃,推荐使用MediaStore写入公共Download目录,无需申请WRITE_EXTERNAL_STORAGE权限:

void writeTextToMediaStore(Context context, ArrayList<String> arrayList) {
    ContentValues values = new ContentValues();
    values.put(MediaStore.MediaColumns.DISPLAY_NAME, "file01.txt");
    values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain");
    values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);

    Uri uri = context.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values);
    if (uri == null) {
        Toast.makeText(context, "创建文件失败", Toast.LENGTH_SHORT).show();
        return;
    }

    try (OutputStream outputStream = context.getContentResolver().openOutputStream(uri);
         OutputStreamWriter writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) {
        for (String str : arrayList) {
            writer.write(str);
            writer.write(System.lineSeparator());
        }
        Toast.makeText(context, "保存成功", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(context, "保存失败", Toast.LENGTH_SHORT).show();
    }
}

调用时直接执行即可,无需权限申请:

writeTextToMediaStore(getApplicationContext(), arrayList);

内容的提问来源于stack exchange,提问作者v_n_y

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:25:26