将 java 用于将资产文件复制到 Android 中的缓存文件夹的代码转换为 Kotlin 的最佳实践
Best practice for converting java code used for copying assets files to cache folder in Android to Kotlin
我正在使用此代码将 Android 中的资产文件复制到缓存文件夹,重点是它是一个 Java 代码,我将其转换为 Kotlin,但它看起来更 Java(ish) 主要围绕 while 循环:
val file = File("${cacheDir.path}/$fileName")
val dir = file.parentFile
dir.mkdirs()
val inputStream = assets.open(fileName)
val bufferedOutputStream = BufferedOutputStream(FileOutputStream(file))
val buf = ByteArray(10240)
var num = inputStream.read(buf)
// Java version: while ((num = fi.read(buf)) > 0)
while (num > 0) {
bufferedOutputStream.write(buf, 0, num)
num = inputStream.read(buf)
}
bufferedOutputStream.close()
inputStream.close()
任何可以使它更像 Kotlin 的专家。
重写它的惯用方法是完全摆脱 while
循环并用 copyTo standard library function.
替换它
实际上在完整翻译后代码应该如下所示:
val file = File("${cacheDir.path}/$fileName")
val dir = file.parentFile
dir.mkdirs()
val inputStream = assets.open(fileName).use { input ->
val bufferedOutputStream = file.outputStream().buffered().use { output ->
input.copyTo(output, 10240)
}
}
这利用了开发者上面提到的两个Closeable.use
extension function, some other handy extension functions and the copyTo
函数来最大限度地简化代码。
PS:Closeable.use
应该是 Java 7 try-with-resource 构造的 kotlin 对应物,具有更好的简单性。
尝试在 kotlin
中使用 class
/**
* @fileName: path of file in assets folder
* For example: getPathFileFromAssets("fonts/text4.ttf") or
*getPathFileFromAssets("text4.ttf")
*/
@Throws(IOException::class)
fun Context.getPathFileFromAssets(fileName: String): String {
var tmpPath = cacheDir.resolve(fileName)
if (tmpPath.exists()) return tmpPath.absolutePath
if (fileName.contains("/")) {
val folder = fileName.split("/")[0]
File(cacheDir, folder).also {
if (it.exists().not()) {
it.mkdirs()
}
}
}
tmpPath = File(cacheDir, fileName).also {
it.outputStream()
.use { cache ->
assets.open(fileName)
.use { it.copyTo(cache) }
}
}
return tmpPath.absolutePath
}
用于Activity
try {
val pathFile = getPathFileFromAssets("fonts/text5.ttf")
val pathFile2 = getPathFileFromAssets("text5.ttf")
} catch (e: IOException) {
}
注意:您必须在 assets 文件夹 中包含文件 text5.ttf 或assets/fonts
我正在使用此代码将 Android 中的资产文件复制到缓存文件夹,重点是它是一个 Java 代码,我将其转换为 Kotlin,但它看起来更 Java(ish) 主要围绕 while 循环:
val file = File("${cacheDir.path}/$fileName")
val dir = file.parentFile
dir.mkdirs()
val inputStream = assets.open(fileName)
val bufferedOutputStream = BufferedOutputStream(FileOutputStream(file))
val buf = ByteArray(10240)
var num = inputStream.read(buf)
// Java version: while ((num = fi.read(buf)) > 0)
while (num > 0) {
bufferedOutputStream.write(buf, 0, num)
num = inputStream.read(buf)
}
bufferedOutputStream.close()
inputStream.close()
任何可以使它更像 Kotlin 的专家。
重写它的惯用方法是完全摆脱 while
循环并用 copyTo standard library function.
实际上在完整翻译后代码应该如下所示:
val file = File("${cacheDir.path}/$fileName")
val dir = file.parentFile
dir.mkdirs()
val inputStream = assets.open(fileName).use { input ->
val bufferedOutputStream = file.outputStream().buffered().use { output ->
input.copyTo(output, 10240)
}
}
这利用了开发者上面提到的两个Closeable.use
extension function, some other handy extension functions and the copyTo
函数来最大限度地简化代码。
PS:Closeable.use
应该是 Java 7 try-with-resource 构造的 kotlin 对应物,具有更好的简单性。
尝试在 kotlin
中使用 class/**
* @fileName: path of file in assets folder
* For example: getPathFileFromAssets("fonts/text4.ttf") or
*getPathFileFromAssets("text4.ttf")
*/
@Throws(IOException::class)
fun Context.getPathFileFromAssets(fileName: String): String {
var tmpPath = cacheDir.resolve(fileName)
if (tmpPath.exists()) return tmpPath.absolutePath
if (fileName.contains("/")) {
val folder = fileName.split("/")[0]
File(cacheDir, folder).also {
if (it.exists().not()) {
it.mkdirs()
}
}
}
tmpPath = File(cacheDir, fileName).also {
it.outputStream()
.use { cache ->
assets.open(fileName)
.use { it.copyTo(cache) }
}
}
return tmpPath.absolutePath
}
用于Activity
try {
val pathFile = getPathFileFromAssets("fonts/text5.ttf")
val pathFile2 = getPathFileFromAssets("text5.ttf")
} catch (e: IOException) {
}
注意:您必须在 assets 文件夹 中包含文件 text5.ttf 或assets/fonts