Kotlin 文件工具类
沙盒内文件和图像的读写和删除。
Context 使用 应用全局上下文 ApplicationContext,在示例代码中为顶层属性 appContext
获取 应用全局上下文 ApplicationContext 的方法
代码
package com.example.fileio.util
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.BitmapFactory
import android.util.Log
import java.io.File
/**
* 读文本。内部存储空间目录(沙盒)的 files 目录下。
*/
fun read(pathname: String): String {
if (pathname.isEmpty()) {
Log.e("sgx", "pathname 不可为空字符串")
return ""
}
val file = File(appContext.filesDir, pathname)
if (!file.exists()) {
Log.e("sgx", "文件不存在")
return ""
}
if (file.isDirectory) {
Log.e("sgx", "文件是目录,无法读取文本")
return ""
}
return file.readText()
}
/**
* 写文本(覆盖)。内部存储空间目录(沙盒)的 files 目录下。
*/
fun write(pathname: String, text: String) {
if (pathname.isEmpty()) {
Log.e("sgx", "pathname 不可为空字符串")
return
}
val file = File(appContext.filesDir, pathname)
createParentDirectory(file)
file.writeText(text)
}
/**
* 写文本(追加)。内部存储空间目录(沙盒)的 files 目录下。
*/
fun append(pathname: String, text: String) {
if (pathname.isEmpty()) {
Log.e("sgx", "pathname 不可为空字符串")
return
}
val file = File(appContext.filesDir, pathname)
createParentDirectory(file)
file.appendText(text)
}
/**
* 遍历文件夹。内部存储空间目录(沙盒)的 files 目录下。
*/
fun walk(pathname: String): MutableList<String> {
val fileNames = mutableListOf<String>()
File(appContext.filesDir, pathname).walk()
// .maxDepth(1) //需遍历的目录层级,为1,即只遍历第一层目录
// .filter { it.isFile } // 只挑选文件,不处理文件夹
// .filter { it.extension in listOf("png", "jpg") } // 选择扩展名为png和jpg的图片文件
.forEach { fileNames.add(it.name) }
return fileNames
}
/**
* 读取图片,返回图片Bitmap。内部存储空间目录(沙盒)的 files 目录下。
* 返回值类型为可空 Bitmap? ,否则图片不存在时会崩溃。
*/
fun readBitmap(pathname: String): Bitmap? {
val path = appContext.filesDir.path + "/" + pathname
return BitmapFactory.decodeFile(path)
}
/**
* 保存图片。内部存储空间目录(沙盒)的 files 目录下。
*/
fun writeBitmap(
bitmap: Bitmap,
pathname: String,
compressFormat: CompressFormat,
quality: Int = 100
) {
if (pathname.isEmpty()) {
Log.e("sgx", "pathname 不可为空字符串")
return
}
val file = File(appContext.filesDir, pathname)
createParentDirectory(file)
val outputStream = file.outputStream()
// 压缩格式为 CompressFormat,压缩质量为 quality(80 表示 80%)
bitmap.compress(compressFormat, quality, outputStream)
outputStream.close()
}
/**
* 删除文件和目录。
* 如果是目录,会把目录中的所有子目录和子文件全部删除。
* 如果传入的路径不存在,不会报错,会返回 true 。
* pathname为空字符串,则删除整个 files 文件夹。
*/
fun delete(pathname: String): Boolean {
return File(appContext.filesDir, pathname).deleteRecursively()
}
/**
* 检查文件父目录是否存在,不存在则创建
*/
private fun createParentDirectory(file: File) {
file.parentFile?.apply {
// 父目录不存在,则创建
if (!exists()) {
mkdirs()
}
}
}
- writeText 覆盖写入文本
- appendText 往源文件追加文本
- writeBytes 覆盖写入字节数组
- appendBytes 追加字节数组
读写文本,遍历文件夹
调用
package com.example.fileio
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.example.fileio.util.append
import com.example.fileio.util.read
import com.example.fileio.util.walk
import com.example.fileio.util.write
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
write(
pathname = "test/dir3/test.txt",
text = "hello world! \n你好,安卓!\n"
)
val text = read(pathname = "test/dir3/test.txt")
Log.i("sgx", text)
append(
pathname = "test/dir3/test.txt",
text = "hello world! \n你好,世界!\n"
)
Log.i("sgx", read(pathname = "test/dir3/test.txt"))
Log.i("sgx", walk(pathname = "test").toString())
Log.i("sgx", "delete file:" + delete(pathname = "test/dir4/test.json"))
Log.i("sgx", "delete directory:" + delete(pathname = "test/dir4"))
Log.i(
"sgx",
"delete image:" + delete(pathname = "test/dir3/ic_user_portrait.png")
)
}
}
结果
- 调用 walk 遍历文件夹
读写图片
调用
binding.readPng.setOnClickListener {
val bitmap = readBitmap("test/dir3/士兵.png")
binding.imageView.setImageBitmap(bitmap)
}
binding.savePng.setOnClickListener {
val bitmap = binding.imageView.drawable.toBitmap()
writeBitmap(
bitmap = bitmap,
pathname = "test/dir3/soldier.png",
compressFormat = Bitmap.CompressFormat.PNG
)
}
binding.readJpg.setOnClickListener {
val bitmap = readBitmap("test/dir3/陈独秀.jpg")
binding.imageView.setImageBitmap(bitmap)
}
binding.saveJpg.setOnClickListener {
val bitmap = binding.imageView.drawable.toBitmap()
writeBitmap(
bitmap = bitmap,
pathname = "test/dir3/ChenDuXiu.jpg",
compressFormat = Bitmap.CompressFormat.JPEG,
quality = 80
)
}
效果