Kotlin File.copyTo 抛出 FileAlreadyExistsException 并将覆盖设置为 true
Kotlin File.copyTo throws FileAlreadyExistsException with overwrite set to true
我正在开发一个有一些特定要求的应用程序,其中之一是记录在该应用程序上执行的每一个操作:
- 用户执行的操作
- 使用 Timber 记录操作
- 将该行附加到设备外部存储(设备大容量存储)中的日志文件
- 更新可移动外部存储(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为假时,仍然会抛出该异常,说明无法删除目标文件。这可能有多种原因,但这些是最常见的原因:
- 目标文件是一个目录,它仍然包含文件。
- 一些其他进程打开了文件,持有它的锁并防止突变。
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。
我正在开发一个有一些特定要求的应用程序,其中之一是记录在该应用程序上执行的每一个操作:
- 用户执行的操作
- 使用 Timber 记录操作
- 将该行附加到设备外部存储(设备大容量存储)中的日志文件
- 更新可移动外部存储(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为假时,仍然会抛出该异常,说明无法删除目标文件。这可能有多种原因,但这些是最常见的原因:
- 目标文件是一个目录,它仍然包含文件。
- 一些其他进程打开了文件,持有它的锁并防止突变。
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。