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

如何使用ContentResolver设置所创建文件的编码格式?

修复CSV文件编码乱码方案

问题原因

你当前的代码默认使用UTF-8编码生成字节流,而微软Office读取CSV文件时默认使用当前系统区域的编码(俄文地区为Windows-1251)解码,没有BOM标识的UTF-8文件会被错误解码,因此西里尔字符显示乱码。
另外你的代码中存在两处可优化点:

  • openOutputStream可能返回null,需要添加空安全调用
  • use函数会在执行完成后自动关闭流,不需要额外调用out.close()

方案1:指定Windows-1251编码

如果需要适配俄文区域的Office默认编码,直接指定编码转换即可:

private val getContent = registerForActivityResult(ActivityResultContracts.CreateDocument("text/csv")) { uri ->
    uri?.let { writeToFile(requireActivity(), it) }
}

fun writeToFile(context: Context, source: Uri) = viewModelScope.launch(Dispatchers.IO) {
    val contentResolver = context.contentResolver
    contentResolver.openOutputStream(source)?.use { out ->
        // 直接指定Windows-1251编码转换字节
        out.write("id,Цвет,Размер\n".toByteArray(Charsets.Windows_1251))
    }
}

方案2:使用带BOM的UTF-8编码(多区域兼容)

如果需要文件在不同语言区域的设备上都能正常显示,推荐写入UTF-8 BOM头,Office识别到BOM后会自动使用UTF-8解码:

fun writeToFile(context: Context, source: Uri) = viewModelScope.launch(Dispatchers.IO) {
    val contentResolver = context.contentResolver
    contentResolver.openOutputStream(source)?.use { out ->
        // 写入UTF-8 BOM头
        out.write(byteArrayOf(0xEF.toByte(), 0xBB.toByte(), 0xBF.toByte()))
        // 写入UTF-8编码的内容
        out.write("id,Цвет,Размер\n".toByteArray(Charsets.UTF_8))
    }
}

其他编码设置方式

如果需要设置其他编码,只需要替换toByteArray()方法中的编码参数即可,例如:

  • Charsets.UTF_16对应Unicode双字节编码
  • 也可以直接传入编码名称字符串,例如toByteArray(Charset.forName("GBK"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:15:11