/storage/emulated/0/Android/data/zx.com.demo/files/myDir
/storage/emulated/0/Android/data/zx.com.demo/files/zx1001.txt
/storage/emulated/0/Android/data/zx.com.demo/files/app-debug.apk
myDir
zx1001.txt
app-debug.apk
kotlin对File的扩展
以上这些示例中用的都是Java提供的API,kotlin提供了一些扩展方法和扩展属性,可以更加方便的操作文件。
名称 | 作用 |
---|---|
extension | 文件格式的后缀,不包括. ,例如:mp3 |
nameWithoutExtension | 名称,不包括后缀 |
appendBytes(ByteArray) | 追加字节数组到文件末尾 |
writeBytes(ByteArray) | 写入字节数组,如果之前有内容,会被覆盖 |
readBytes(): ByteArray | 以字节数组的形式获取此文件的全部内容,不建议在大文件上使用此方法,上限2G |
appendText(String,Charset) | 追加字符串到文件末尾,默认是UTF-8编码 |
writeText(String,Charset) | 写入字符串,如果之前有内容,会被覆盖 |
readText(Charset): String | 以String 形式获取此文件的全部内容,默认编码UTF-8,不建议在大文件上使用此方法,上限2G |
reader(Charset): InputStreamReader | 返回一个FileReader以读取此文件的内容 |
bufferedReader(Charset, bufferSize: Int): BufferedReader | 返回一个BufferedReader用于读取此文件的内容 |
writer(Charset):OutputStreamWriter | 返回一个FileWriter用于写入此文件 |
bufferedWriter(Charset, bufferSize: Int): BufferedWriter | 返回一个BufferedWriter用于写入此文件 |
forEachBlock(action: (buffer: ByteArray, bytesRead: Int) -> Unit) | 高阶函数,按字节块读取文件并为每个读取的块调用action,字节块默认为4096。适用于大文件 |
forEachLine(Charset, action: (line: String) -> Unit) | 高阶函数,按行读取文件并为每行调用action,适用于大文件 |
readLines( Charset): List | 按行读取文件,不要在大文件上使用此方法 |
copyTo(target: File, overwrite: Boolean = false, bufferSize: Int = DEFAULT_BUFFER_SIZE): File | 复制文件或者文件夹,并且会创建target所需的各个父级文件夹(如果缺少)。overwrite为true时,target可被覆盖,不为true并且当target存在时,返回false,复制失败。overwrite为true并且target是一个文件夹时,只有当文件夹为空时才会被替换。源文件如果是文件夹,则只会创建目标文件夹,不会复制文件夹中的文件。该操作不会保留复制的文件属性,例如创建/修改日期、权限等 |
copyRecursively(target: File, overwrite: Boolean = false, onError: (File, IOException)) | 递归复制文件或者文件夹,并且会创建target所需的各个父级文件夹(如果缺少)。如果源文件是文件夹,将复制文件夹中的所有内容。该操作不会保留复制的文件属性,例如创建/修改日期、权限等。默认自带的错误处理器会将错误抛出,可以传入一个Lambda用来处理异常。复制文件夹失败时,可能已经复制了一部分 |
deleteRecursively() | 递归删除文件或者文件夹,删除文件夹失败时,可能已经删除了一部分 |
.walk() | 自上而下,深度优先,遍历整个文件夹 |
看完这些扩展方法,瞬间觉得Java不香了,感觉都不需要再学IO流了,但是有时候我们并不是只处理文件的IO流,所以Java的IO流还是要学。
IO流
按照“流”的数据流向,可以将其化分为:输入流和输出流。输入和输出是相对于程序而言,数据流入程序中,那就是输入流,数据流出程序,那就是输出流。按照“流”中处理数据的单位,可以将其区分为:字节流(二进制流)和字符流。在java中,字节是占1个Byte,即8位;而字符是占2个Byte,即16位。一般来说, 对于文本编辑器或文本输出程序创建的文件例如.txt、.xml、.java,应该使用字符流来读取, 对于二进制文件例如png、doc, 应该使用字节流来读取。因为字节流操作的是二进制数据,所以字节流不涉及编码。字符流操作的是字符,而字符是有编码的,所以字符流需要指定编码,下方的例子中都是用的默认的UTF-8编码。
字节流的抽象基类:InputStream