Android 中存取文件位置有三种,而且每种各有其读取方式。
- apk 中的只读资源文件
- SD 卡中的文件
- 数据区的文件(/data)
1. 资源文件的读取
有两种资源文件 raw
和 assets
,使用以下两种不同的方式读取:
val rawInputStream = context.resources.openRawResource(R.raw.test)
val assetsInputStream = context.assets.open(fileName)
2. SD 卡数据读写
2.1 获取权限
根据需要在 manifest
中加入以下内容:
<!--写-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--读-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--创建修改-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
2.2 判断 SD 卡状态
Environment.getExternalStorageState()
如果手机装有 SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED
。
2.3 获取 SD 卡根目录
Environment.getExternalStorageDirectory()
2.4 读写
val file = File(Environment.getExternalStorageDirectory(), "a.txt")
val inputStream = FileInputStream(file)
val outStream = FileOutputStream(file)
3. 数据区读写
3.1 写操作
val fout = openFileOutput(fileName, Context.MODE_PRIVATE)
3.2 读操作
val fin = openFileInput(fileName)
3.3 写操作中的使用模式
MODE_APPEND:向文件尾写入数据
MODE_PRIVATE:仅该程序可写入数据
MODE_WORLD_READABLE:所有程序均可读该文件数据
MODE_WORLD_WRITABLE:所有程序均可写入数据
4. File 读写数据区示例
4.1 创建文件夹
private fun makeDir() {
folder = File(filesDir, folderName)
if (folder.exists()) {
log("Directory \"${folder.path}\" existed.")
} else {
folder.mkdir()
log("Create directory \"${folder.path}\".")
}
}
4.2 新建并写文件
private fun createFile() {
file = File(folder, fileName)
if (file.exists()) {
log("File \"${file.path}\" existed.")
} else {
try {
file.createNewFile()
file.appendText("Hello.\n")
log("Create \"${file.path}\" with \"Hello.\"")
} catch (e: Exception) {
e.printStackTrace()
}
}
}
4.3 读文件
private fun readFile() {
if (file.isFile) {
try {
log("Content from \"${file.path}\": ${file.readText(Charset.forName("UTF-8"))}")
} catch (e: Exception) {
e.printStackTrace()
}
}
}
4.4 复制
private fun copyFile() {
copyFile = File(folder, copyName)
if (file.isFile && !copyFile.isFile) {
file.copyTo(copyFile)
log("Copy \"${file.path}\" to \"${copyFile.path}\"")
}
}
4.5 遍历
private fun listFileNames() {
log("Files includes in ${folder.name}: ")
log("--------")
folder.listFiles().forEach {
log(it.name)
}
log("--------")
}
4.6 递归删除文件夹
private fun deleteFolder() {
folder.deleteRecursively()
}
4.7 变量及其它
private fun log(msg: String) {
Log.d(javaClass.simpleName, msg)
outStr += msg
outStr += "\n\n"
}
private lateinit var folder: File
private lateinit var file: File
private lateinit var copyFile: File
private var outStr = ""
companion object {
private val folderName = "xandeer"
private val fileName = "a.txt"
private val copyName = "a_copy.txt"
}
4.8 运行结果
点击菜单 View -> Tool Windows -> Device File Explorer
,可查看当前虚拟机的文件系统,在 /data/user/0/me.xandeer.examples/files
中即可看到示例中添加的文件夹和文件。