You need to enable JavaScript to run this app. Kotlin Native iOS端FileSeek、getFileLength、readIntoBuffer的正确实现
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Native iOS端FileSeek、getFileLength、readIntoBuffer的正确实现

Kotlin Native iOS端DFU工具文件操作实现修正

现有iOS端代码的核心失效点

  • readIntoBuffer入参赋值完全无效:Kotlin函数入参默认是不可重新赋值的val类型,代码中写buffer = read.toByteArray()仅修改了函数内部的局部引用,完全不会改动调用方传入的原始buffer对象,导致上层始终读不到文件内容。
  • EOF行为不符合跨平台约定:当前实现读到文件末尾时,readDataOfLength返回空NSData,方法返回0,和公共层约定的「文件读完返回-1」、Android端RandomAccessFile.read()的行为不一致,会导致DFU读取流程出现死循环。
  • 空指针崩溃风险:NSFileHandle.fileHandleForReadingAtPath在文件不存在、无访问权限时会返回null,直接强解!!会触发无提示崩溃。
  • 文件句柄资源泄漏:原实现未在对象销毁时关闭打开的文件句柄,长期运行会触发iOS系统的文件描述符上限限制。

修正后的iOS端actual实现

actual class PlatformFile actual constructor(filePath: String) {
    // 打开文件时做非空校验,避免强解崩溃
    private val fileHandle = NSFileHandle.fileHandleForReadingAtPath(filePath) 
        ?: error("无法打开目标文件,路径: $filePath")

    // 对象销毁时自动释放文件句柄
    protected fun finalize() {
        fileHandle.closeFile()
    }

    actual fun setPosition(start: Long) {
        // 从文件头定位到指定偏移,和Android端seek行为完全对齐
        fileHandle.seekToFileOffset(start.toULong())
    }

    actual fun getLength(): Long {
        // 记录当前读指针位置,查询完文件大小后恢复,不影响后续读流程
        val currentOffset = fileHandle.offsetInFile
        val totalSize = fileHandle.seekToEndOfFile()
        fileHandle.seekToFileOffset(currentOffset)
        return totalSize.toLong()
    }

    actual fun readIntoBuffer(buffer: ByteArray): Int {
        val requestReadSize = buffer.size.toULong()
        if (requestReadSize.toLong() <= 0) return 0

        val readData = fileHandle.readDataOfLength(requestReadSize)
        // 读到文件末尾时按公共层约定返回-1
        if (readData.length.toLong() == 0L) return -1

        // 核心修正:把读取到的字节内容拷贝到传入的原始buffer中,而非替换局部引用
        readData.toByteArray().copyInto(
            destination = buffer,
            destinationOffset = 0,
            startIndex = 0,
            endIndex = readData.length.toInt()
        )

        return readData.length.toInt()
    }
}

实现对齐说明

  • 全链路行为和Android端RandomAccessFile保持一致:定位时从文件头计算偏移、获取文件大小时不移动当前读指针、读到文件末尾返回-1、返回实际读取到的字节数。
  • 解决了原实现中buffer无内容写入的核心问题:所有读取操作的写入目标是调用方持有的原始数组对象,不会出现局部引用替换导致的数据丢失。
  • 优化了文件大小的获取逻辑:通过文件句柄直接查询总大小,避免了每次调用NSFileManager遍历文件属性的性能开销,适配DFU流程中频繁读取分片的性能要求。
  • 增加了文件句柄的生命周期管理,避免资源泄漏。

注意:该实现兼容Kotlin/Native当前绑定的全版本iOS系统,无需额外适配iOS 13+的新错误处理接口,可直接复用在固件读取的DFU流程中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 17:24:03