【问题标题】:Kotlin File.copyTo throws FileAlreadyExistsException with overwrite set to trueKotlin File.copyTo 抛出 FileAlreadyExistsException,覆盖设置为 true
【发布时间】:2019-10-31 04:33:46
【问题描述】:

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

  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

我读到here 仅当目标文件已经存在并且覆盖false 时,此异常is thrown,但我已将其设置为true

有人经历过吗?我怎样才能让它工作?

#注意: 我知道这可能超出了 Android 标准/指南,这不是通用应用程序,而是为满足客户规范而设计和开发的产品。

【问题讨论】:

  • 我相信你之前问过这个,但删除了你的问题和我的 cmets。正如我从以前的 cmets 中回忆的那样,您没有对可移动存储上任意位置的读/写访问权限。如果您对此位置没有写入权限,则会触发 Kiskae 在this answer 中概述的行为。

标签: android file kotlin overwrite


【解决方案1】:

参考您链接的确切代码:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    详情请见KT-27545

    【讨论】:

      猜你喜欢
      • 2017-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      相关资源
      最近更新 更多