文件操作
遍历 | walk() | 自上而下,深度优先,遍历整个文件夹。 |
walkBottomUp() | 自下而上的顺序遍历文件目录和内容。 | |
walkTopDown() | 自上而下的顺序遍历文件目录和内容。 | |
名称 | extension() | 文件名的后缀格式,不包含“.”,例如 mp3。 |
nameWithoutExtension() | 文件名,不包含后缀。 |
Kotlin把目录遍历这个功能重新梳理了一下,归纳为FileTreeWalk文件树。首先调用File对象的walk方法得到FileTreeWalk实例,接着依次为该实例设置具体的条件,包括遍历深度、是否匹配文件夹、文件扩展名,以及最后的文件队列循环处理。
//遍历文件
file.parentFile //获取上级目录
.walk() //先访问文件夹,再访问里面的内容
.maxDepth(1)//需遍历的目录层级为1,即无需检查子目录
.filter { it.isFile } //只挑选文件,不处理文件夹
.filter { it.extension in listOf("png","jpg") } //选择扩展名为png和jpg的图片文件
// .filter { it.extension.equals("txt", true) }
.forEach(::println)//循环处理符合条件的文件
//文件拷贝
file.copyTo(File(file.parent, "copy.txt"), true)
//文件夹拷贝
//target:新地址
//overwrite:是否覆盖
//onError:失败的回调
file.parentFile.copyRecursively(
File(file.parentFile.parentFile.parent, "copyRecursively"),
true
)
流操作
读 | readBytes() | public fun File.readBytes(): ByteArray 以 ByteArray 形式返回读取到的全部文件内容,上限2G。 |
readText() | File.readText(charset: Charset = Charsets.UTF_8): String 以 String 形式返回读取到的全部文件内容,上限2G,默认编码UTF-8。 | |
readLines() | public fun File.readLines(charset: Charset = Charsets.UTF_8): List<String> 以 List<String> 形式返回读取到的文件全部内容,一行内容是一个元素,只能是文本。不要在大文件上使用此方法。 | |
useLines() | public inline fun <T> File.useLines(charset: Charset = Charsets.UTF_8, block: (Sequence<String>) -> T): T 拿到所有行的序列,并调用action。 | |
forEachLine() | public fun File.forEachLine(charset: Charset = Charsets.UTF_8, action: (line: String) -> Unit): Unit 按行读取文件并为每行调用action,适用于大文件。 | |
forEachBlock() | public fun File.forEachBlock(action: (buffer: ByteArray, bytesRead: Int) -> Unit): Unit 按字节块读取文件并为每个读取的块调用action,字节块默认为4096最小为512。适用于大文件。 | |
写 | writeBytes() | public fun File.appendBytes(array: ByteArray): Unit 写入字节数组,已有同名文件会覆盖。 |
writeText() | public fun File.writeText(text: String, charset: Charset = Charsets.UTF_8): Unit 写入字符串,已有同名文件会覆盖。 | |
appendBytes() | public fun File.writeBytes(array: ByteArray): Unit 追加字节数组到文件末尾。 | |
appendText() | public fun File.appendText(text: String, charset: Charset = Charsets.UTF_8): Unit 追加字符串到文件末尾。 | |
拷贝 | copyTo() | 复制文件或者文件夹,并且会创建target所需的各个父级文件夹(如果缺少)。overwrite为true时,target可被覆盖,不为true并且当target存在时,返回false,复制失败。overwrite为true并且target是一个文件夹时,只有当文件夹为空时才会被替换。源文件如果是文件夹,则只会创建目标文件夹,不会复制文件夹中的文件。该操作不会保留复制的文件属性,例如创建/修改日期、权限等。 |
copyRecursively() | 递归复制文件或者文件夹,并且会创建target所需的各个父级文件夹(如果缺少)。如果源文件是文件夹,将复制文件夹中的所有内容。该操作不会保留复制的文件属性,例如创建/修改日期、权限等。默认自带的错误处理器会将错误抛出,可以传入一个Lambda用来处理异常。复制文件夹失败时,可能已经复制了一部分。 | |
删除 | deleteRecursively() | 递归删除文件或者文件夹,删除文件夹失败时,可能已经删除了一部分。 |
Java流对象 | inputStream() outputStream() | public inline fun File.inputStream(): FileInputStream |
public inline fun File.outputStream(): FileOutputStream | ||
reader() writer() | public inline fun File.reader(charset: Charset = Charsets.UTF_8): InputStreamReader 返回一个InputStreamReader以读取此文件的内容。 | |
public inline fun File.writer(charset: Charset = Charsets.UTF_8): OutputStreamWriter 返回一个OutputStreamWriter用于写入此文件。 | ||
bufferedReader() bufferedWriter() | public inline fun File.bufferedReader(charset: Charset = Charsets.UTF_8, bufferSize: Int = DEFAULT_BUFFER_SIZE): BufferedReader 返回一个BufferedReader用于读取此文件的内容,默认大小8*1024。 | |
public inline fun File.bufferedWriter(charset: Charset = Charsets.UTF_8, bufferSize: Int = DEFAULT_BUFFER_SIZE): BufferedWriter 返回一个BufferedWriter用于写入此文件。 | ||
printWrite() | public inline fun File.printWriter(charset: Charset = Charsets.UTF_8): PrintWriter |
val file = File("m:\\demo.txt")
fun read() {
println(file.readText()) //段落之间有换行
file.readLines().forEach(::println)
file.forEachLine { println(it) }
file.forEachBlock { buffer, bytesRead -> print(buffer.decodeToString()) }
file.bufferedReader().use { it.readLines().forEach(::println) }
file.inputStream().use {
//一个个读取太慢
// var num: Int
// while (it.read().also { num = it } != -1) {
// print(num.toChar())
// }
// }
val arr = ByteArray(1024)
var num: Int
while (it.read(arr).also { num = it } != -1) {
print(arr.decodeToString(0, num)) //使用num而不是arr.size是因为最后一次读取不一定能读满,不然后面全时空格
// print(String(arr, 0, num)) //效果同上
}
}
}
fun write() {
//覆盖
file.writeBytes("writeBytes\n".toByteArray())
file.writeText("writeText\n")
file.outputStream().use { it.write("outputStream\n".toByteArray()) }
file.printWriter().use { it.println("printlnWriter") }
file.bufferedWriter().use { it.write("bufferedWriter") }
//追加
file.appendBytes("appendBytes".toByteArray())
file.appendText("appendText")
}