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

如何在Kotlin Multiplatform中向Android/iOS文件系统写入文本及示例需求

Kotlin Multiplatform 跨平台写入文本文件方案

由于Kotlin Multiplatform(KMM)没有提供统一的跨平台文件系统API,必须通过expect/actual机制分别实现Android和iOS平台的文件写入逻辑,以下是完整示例:


1. 通用模块定义expect函数

在commonMain源码集中定义平台无关的抽象函数,声明我们需要的文件写入能力:

// commonMain/src/.../FileOperations.kt
expect suspend fun writeTextToFile(filename: String, content: String): Boolean
  • suspend标记:文件IO属于耗时操作,用协程避免阻塞主线程
  • 返回值Boolean:表示写入操作是否成功

2. Android平台actual实现

在androidMain源码集中实现Android端的文件写入逻辑,使用应用内部存储(无需权限):

// androidMain/src/.../FileOperations.kt
import android.content.Context
import java.io.File

// 全局Context持有者,在Application初始化时赋值
object AppContextHolder {
    lateinit var context: Context
}

actual suspend fun writeTextToFile(filename: String, content: String): Boolean {
    return try {
        // 获取应用内部files目录路径
        val targetFile = File(AppContextHolder.context.filesDir, filename)
        targetFile.writeText(content)
        true
    } catch (e: Exception) {
        e.printStackTrace()
        false
    }
}

初始化Context持有者:

在自定义Application类中完成Context赋值:

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        AppContextHolder.context = this
    }
}

3. iOS平台actual实现

在iosMain源码集中基于iOS Foundation框架实现,写入应用沙盒的Documents目录:

// iosMain/src/.../FileOperations.kt
import platform.Foundation.NSFileManager
import platform.Foundation.NSUTF8StringEncoding
import platform.Foundation.writeToURL

actual suspend fun writeTextToFile(filename: String, content: String): Boolean {
    return try {
        val fileManager = NSFileManager.defaultManager()
        // 获取Documents目录URL
        val documentsDir = fileManager.URLsForDirectory(
            directory = platform.Foundation.NSDocumentDirectory,
            inDomains = platform.Foundation.NSUserDomainMask
        ).first()!!
        val targetURL = documentsDir.URLByAppendingPathComponent(filename)
        
        content.writeToURL(
            url = targetURL,
            atomically = true,
            encoding = NSUTF8StringEncoding,
            error = null
        )
        true
    } catch (e: Exception) {
        println("iOS文件写入失败:${e.localizedDescription}")
        false
    }
}

4. 通用模块调用示例

在commonMain中直接调用抽象函数,无需关心平台差异:

// commonMain/src/.../DataSaver.kt
suspend fun saveUserPreferences() {
    val success = writeTextToFile("user_prefs.txt", "theme=dark&notifications=true")
    if (success) {
        println("偏好设置保存成功")
    } else {
        println("偏好设置保存失败")
    }
}

注意事项

  • Android端若需写入外部存储,Android 10及以上需使用MediaStore,Android 10以下需申请WRITE_EXTERNAL_STORAGE权限
  • iOS端沙盒限制严格,仅能写入应用允许的目录(Documents、Cache等),若需让用户通过文件应用访问,需在Info.plist中开启UIFileSharingEnabled
  • 实际项目中建议完善异常处理逻辑,避免仅打印日志

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:40:52