跳转至

协程读取文件

协程读取文件

package com.linkdom.readbook.learning

import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.InputStreamReader


@Composable
fun Test() {
    val context = LocalContext.current
    val text = remember { mutableStateOf("") }
    val coroutineScope = rememberCoroutineScope()
//    val scrollState = rememberScrollState()
    Column (
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
            ){
        Button(onClick = {
            coroutineScope.launch {
                readFile(context){
                    text.value = text.value + "\n" + it
                }
            }
        }) {
            Text("读取文件")
        }
        Text(
            text = text.value,
            modifier = Modifier
                .fillMaxSize()
                .verticalScroll(rememberScrollState())
                .padding(10.dp)

        )
    }
}

@OptIn(DelicateCoroutinesApi::class)
private fun readFile(
    context: Context,
    onRead: (String) -> Unit
) {
    GlobalScope.launch(Dispatchers.IO) {
//        println("${Thread.currentThread().name}执行文件读取任务。\n")
        val inputStream = context.assets.open("第一章:刹车时代.txt")
        val bufferedReader = BufferedReader(InputStreamReader(inputStream))
        var line: String? = bufferedReader.readLine()
        while (line != null) {
            onRead(line)
            line = bufferedReader.readLine()
        }
    }
}

@Preview(showBackground = true)
@Composable
fun Test4() {
    Test()
}

注:就这一点困扰了自己很多天,还是自己不够理解协程加载文件的原理,还有读取文件目录的资源,还有诸如让text可以滑动等等功能。。。

对于Compose协程加载文件

@Composable
fun Test() {
    val context = LocalContext.current
    val text = remember { mutableStateOf("") }
    val coroutineScope = rememberCoroutineScope()
    Column (
        ...
            ){
        Button(onClick = {
            coroutineScope.launch {
                readFile(context){
                    text.value = text.value + "\n" + it
                }
            }
        }) {
            Text("读取文件")
        }
        Text(
            text = text.value,
            ...
        )
    }
}

读取本地资源文件

val inputStream = context.assets.open("第一章:刹车时代.txt")

这个context.assets的路径就是要将tmp.txt文件移动到app/src/main/assets文件夹下(如果没有该文件夹,请创建一个)(问GPT才知道的)。

可上下滑动的text

Text(
    text = text.value,
    modifier = Modifier
        .fillMaxSize()
        .verticalScroll(rememberScrollState())
        .padding(10.dp)
)

就是加一个modifier中的.verticalScroll(rememberScrollState())即可;

可参考官方文档:手势 | Jetpack Compose | Android Developers

改进版

不用button触发,直接是点击加载,重写readfile,上面的readfile函数是逐行加载的,这里的是异步一次性加载完毕;

package com.linkdom.readbook.fileio.readFile

import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.InputStreamReader


@Composable
fun Test5() {
    val context = LocalContext.current
    val text = remember { mutableStateOf("") }
    val coroutineScope = rememberCoroutineScope()
//    val scrollState = rememberScrollState()
    remember {
        coroutineScope.launch {
            readFile(context, "第一章:刹车时代"){
                text.value = it
            }
        }
    }
    Column (
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ){
        Text(
            text = text.value,
            modifier = Modifier
                .fillMaxSize()
                .verticalScroll(rememberScrollState())
                .padding(10.dp)

        )
    }
}

@OptIn(DelicateCoroutinesApi::class)
fun readFile(
    context: Context,
    chapterName: String,
    onRead: (String) -> Unit,
) {
    GlobalScope.launch(Dispatchers.IO) {
        val chapterPath = "$chapterName.txt"
        val inputStream = context.assets.open(chapterPath)
        val bufferedReader = BufferedReader(InputStreamReader(inputStream))
        var line: String? = bufferedReader.readLine()
        var allText = ""
        while (line != null) {
            allText = allText + "\n" + line
            line = bufferedReader.readLine()
        }
        onRead(allText)
    }
}

@Preview(showBackground = true)
@Composable
fun Test51() {
    Test5()
}