通常Java的文件操作是编程语言中最复杂的之一,所以我们有必要自己简单封装一下文件的一些操作,如文件(夹)创建、复制、删除、移动、重命名,文件读写,计算文件夹大小,以及路径处理。
创建文件夹
fun createFolder(dirs: Array<String>) {
for (dir in dirs) {
createFolder(dir)
}
}
fun createFolder(dir: String) {
if (dir != "") {
val folder = File(dir)
if (!folder.exists()) {
folder.mkdirs()
}
}
}
文件复制
private fun copyFile(file: File, dstDir: String): Boolean {
val dstFolder = File(dstDir)
if (!dstFolder.exists() || !file.isFile || !dstFolder.isDirectory) {
return false
}
try {
val inStream: InputStream = FileInputStream(file)
val outStream: OutputStream = BufferedOutputStream(
FileOutputStream(File(dstFolder, file.name))
)
var len: Int
val buf = ByteArray(1024)
while (inStream.read(buf).also { len = it } != -1) {
outStream.write(buf, 0, len)
}
outStream.flush()
if (outStream != null) {
outStream.close()
}
if (inStream != null) {
inStream.close()
}
} catch (e: FileNotFoundException) {
e.printStackTrace()
return false
} catch (e: IOException) {
e.printStackTrace()
return false
}
return true
}
private fun copyFolder(file: File, dstDir: String): Boolean {
val dstFolder = File(dstDir)
if (!dstFolder.exists() || !file.isDirectory || !dstFolder.isDirectory) {
return false
}
if (file.list() != null) {
val children = file.list()
for (i in children.indices) {
val newDirFile = File(dstDir + File.separator + file.name)
if (!newDirFile.exists()) {
newDirFile.mkdir()
}
copy(File(file, children[i]), dstDir + File.separator + file.name)
}
}
return true
}
fun copy(file: File, dstDir: String): Boolean {
val dstFolder = File(dstDir)
if (!dstFolder.exists() || !dstFolder.isDirectory) {
return false
}
return if (file.isFile) {
copyFile(file, dstDir)
} else {
copyFolder(file, dstDir)
}
}
文件删除
private fun deleteFile(file: File): Boolean {
return file.isFile && file.delete()
}
private fun deleteFolder(file: File): Boolean {
return if (!file.isDirectory) {
false
} else {
if (file.list() != null) {
val children = file.list()
for (i in children.indices) {
delete(File(file, children[i]))
}
}
file.delete()
}
}
fun delete(file: File): Boolean {
return if (file.isFile) {
deleteFile(file)
} else {
deleteFolder(file)
}
}
文件移动
private fun moveFile(file: File, dstDir: String): Boolean {
val dstFolder = File(dstDir)
return if (!file.isFile || !dstFolder.exists() || !dstFolder.isDirectory) {
false
} else {
copyFile(file, dstDir)
deleteFile(file)
true
}
}
private fun moveFolder(file: File, dstDir: String): Boolean {
val dstFolder = File(dstDir)
return file.isDirectory || !dstFolder.exists() || (!dstFolder.isDirectory
&& copyFolder(file, dstDir) && deleteFolder(file))
}
fun move(file: File, dstDir: String): Boolean {
val dstFolder = File(dstDir)
if (!dstFolder.exists() || !dstFolder.isDirectory) {
return false
}
return if (file.isFile) {
moveFile(file, dstDir)
} else {
copyFolder(file, dstDir) && delete(file)
}
}
文件重命名
private fun renameFile(file: File, name: String): Boolean {
return if (!file.isFile) {
false
} else {
file.renameTo(File(file.parent, name))
}
}
private fun renameFolder(file: File, name: String): Boolean {
return if (!file.isDirectory) {
false
} else {
val parent = file.parent
file.renameTo(File(parent, name))
}
}
fun rename(file: File, name: String): Boolean {
return if (file.isFile) {
renameFile(file, name)
} else {
renameFolder(file, name)
}
}
读取二进制文件
fun read(file: File): ByteArray {
val buffers = ByteArray(1024)
val baos = ByteArrayOutputStream()
val `is` = FileInputStream(file)
var len: Int
while (`is`.read(buffers).also { len = it } > 0) {
baos.write(buffers, 0, len)
}
val fileBytes = baos.toByteArray()
baos.close()
`is`.close()
return fileBytes
}
读取文本文件
fun readText(file: File): String {
val `is` = FileInputStream(file)
val baos = ByteArrayOutputStream()
val buffer = ByteArray(1024 * 4)
var len: Int
while (`is`.read(buffer).also { len = it } != -1) {
baos.write(buffer, 0, len)
}
val data = baos.toByteArray()
return String(data)
}
fun readText(filePath: String): String {
return readText(File(filePath))
}
写文件
fun write(bytes: ByteArray, filePath: String) {
var fos: FileOutputStream? = null
try {
val file = File(filePath)
if (!file.parentFile.exists()) {
file.parentFile.mkdirs()
}
fos = FileOutputStream(file)
fos.write(bytes)
fos.flush()
} finally {
close(fos)
}
}
fun write(inputStream: InputStream, filePath: String): File {
var outputStream: OutputStream? = null
val file = File(filePath)
if (!file.parentFile.exists()) {
file.parentFile.mkdirs()
}
try {
outputStream = FileOutputStream(file)
val buffer = ByteArray(4 * 1024)
var lenght = 0
while (inputStream.read(buffer).also { lenght = it } > 0) {
outputStream.write(buffer, 0, lenght)
}
outputStream.flush()
} catch (e: IOException) {
e.printStackTrace()
} finally {
close(inputStream)
close(outputStream)
}
return file
}
fun close(vararg closeableList: Closeable?) {
try {
for (closeable in closeableList) {
closeable?.close()
}
} catch (ignore: IOException) {
}
}
计算文件夹大小
fun formatFileSize(size: Double): String {
val kiloByte = size / 1024
if (kiloByte < 1 && size > 0) {
return size.toString() + "B"
} else if (size <= 0) {
return "0B"
}
val megaByte = kiloByte / 1024
if (megaByte < 1) {
val result1 = BigDecimal(kiloByte.toString())
return result1.setScale(2, BigDecimal.ROUND_HALF_UP)
.toPlainString() + "KB"
}
val gigaByte = megaByte / 1024
if (gigaByte < 1) {
val result2 = BigDecimal(megaByte.toString())
return result2.setScale(2, BigDecimal.ROUND_HALF_UP)
.toPlainString() + "MB"
}
val teraBytes = gigaByte / 1024
if (teraBytes < 1) {
val result3 = BigDecimal(gigaByte.toString())
return result3.setScale(2, BigDecimal.ROUND_HALF_UP)
.toPlainString() + "GB"
}
val result4 = BigDecimal(teraBytes)
return (result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString()
+ "TB")
}
fun getFolderTotalSize(file: File): Long {
var size: Long = 0
try {
val files = file.listFiles()
val subCount: Int
if (files != null) {
subCount = files.size
for (i in 0 until subCount) {
size = if (files[i].isDirectory) {
size + getFolderTotalSize(files[i])
} else {
size + files[i].length()
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
return size
}
fun getSubFilesCount(folder: File): Int {
return if (!folder.isDirectory) {
-1
} else {
folder.list().size
}
}
路径处理
fun getParentPath(path: String): String {
var path = path
if (path.endsWith(File.separator)) {
path = path.substring(0, path.length - 1)
}
val start = path.lastIndexOf(File.separator)
return path.substring(0, start)
}
fun getFileNameFromPath(path: String): String {
return getFileNameFromPath(path, true)
}
fun getNameFromPath(path: String): String {
return getFileNameFromPath(path, false)
}
private fun getFileNameFromPath(path: String, withSuffix: Boolean): String {
val start = path.lastIndexOf(File.separator) + 1
val end = path.lastIndexOf(".")
return if (withSuffix) {
path.substring(start)
} else {
path.substring(start, end)
}
}