Kotlin File.copyTo 抛出 FileAlreadyExistsException 并将覆盖设置为 true

Kotlin File.copyTo throws FileAlreadyExistsException with overwrite set to true

我正在开发一个有一些特定要求的应用程序,其中之一是记录在该应用程序上执行的每一个操作:

  1. 用户执行的操作
  2. 使用 Timber 记录操作
  3. 将该行附加到设备外部存储(设备大容量存储)中的日志文件
  4. 更新可移动外部存储(SD 卡)中该文件的副本

每当执行某个操作时,我都会使用 Timber.i("log message") 并且我已将 log(Int, String, String, Throwable) 方法覆盖到我执行其他操作的位置:

override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
    if (priority == Log.INFO) {
        appendToLog(message);
    }
}

appendToLog(String) 是:

private fun appendToLog(message: String) {
    // skipping the unnecessary code which transforms some info in a string, this works fine
    val log = LogData(...)

    // pathManager.getLogFile() returns a File and works
    val fw = FileWriter(pathManager.getLogFile(),true)
    // log.checksum() and log.encrypt() return a String, this works fine
    val checksum = log.checksum()
    val encrypted = log.encrypt()
    fw.write(encrypted.plus("--!").plus(checksum))
    fw.close()


    // copying log file to sd
    pathManager.getLogFile()
        .copyTo(pathManager.getSdLogFile(), true) // the exception is thrown here

}

抛出的异常如下,由于法律原因不能添加其他细节,这就是异常的所有相关信息

kotlin.io.FileAlreadyExistsException:
my/file/path -> my/file/path: The destination file already exists

我只在目标文件已经存在并且覆盖false时读取here that this exception is thrown,但我已将其设置为true

有人遇到过这种情况吗?我怎样才能让它工作?

#注: 我知道这可能是出于Android standards/guidelines,这不是一个普通的应用程序,而是一个为满足客户规格而设计和开发的产品。

指的是您链接的确切代码:

val stillExists = if (!overwrite) true else !target.delete()

overwrite为真,File#delete returns为假时,仍然会抛出该异常,说明无法删除目标文件。这可能有多种原因,但这些是最常见的原因:

  1. 目标文件是一个目录,它仍然包含文件。
  2. 一些其他进程打开了文件,持有它的锁并防止突变。

File#delete javadoc 指的是 Files#delete 方法,如果您想要更好地了解删除失败的原因,在调用 File.copyTo 之前手动调用它可以让您识别失败的原因。

从 Kotlin 1.3.60 开始,如果 overwrite 标志为真并且删除目标文件失败,File.copyTo 将报告一条明显的错误消息:

$from -> $to: Tried to overwrite the destination, but failed to delete it.

详情见KT-27545