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
相关产品推荐
相关产品推荐

