420 lines
12 KiB
Kotlin
420 lines
12 KiB
Kotlin
package com.android.grape.util
|
|
|
|
import android.os.Environment
|
|
import android.util.Log
|
|
import com.blankj.utilcode.util.LogUtils
|
|
import java.io.BufferedInputStream
|
|
import java.io.BufferedOutputStream
|
|
import java.io.BufferedReader
|
|
import java.io.BufferedWriter
|
|
import java.io.File
|
|
import java.io.FileInputStream
|
|
import java.io.FileNotFoundException
|
|
import java.io.FileOutputStream
|
|
import java.io.FileWriter
|
|
import java.io.IOException
|
|
import java.io.InputStream
|
|
import java.io.InputStreamReader
|
|
import java.io.OutputStream
|
|
import java.io.RandomAccessFile
|
|
import java.io.UnsupportedEncodingException
|
|
import java.nio.charset.StandardCharsets
|
|
import java.util.Enumeration
|
|
import java.util.zip.ZipEntry
|
|
import java.util.zip.ZipFile
|
|
|
|
|
|
/**
|
|
* @author litianxiang
|
|
* @description:
|
|
* @date :2021/9/28 15:44
|
|
*/
|
|
object FileUtils {
|
|
private const val TAG = "IOSTQ:FileUtils"
|
|
private const val BUFFER_SIZE = 1024 * 1024 //1M Byte
|
|
|
|
|
|
//创建文件夹
|
|
fun createDir(destDirName: String): Boolean {
|
|
var destDirName = destDirName
|
|
val dir = File(destDirName)
|
|
if (dir.exists()) {
|
|
println("创建目录" + destDirName + "失败,目标目录已经存在")
|
|
return false
|
|
}
|
|
if (!destDirName.endsWith(File.separator)) {
|
|
destDirName = destDirName + File.separator
|
|
}
|
|
//创建目录
|
|
if (dir.mkdirs()) {
|
|
Log.e("createDir", "创建目录" + destDirName + "成功!")
|
|
return true
|
|
} else {
|
|
Log.e("createDir", "创建目录" + destDirName + "失败!")
|
|
return false
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 创建文件
|
|
*
|
|
* @param filePath 文件地址
|
|
* @param fileName 文件名
|
|
* @return
|
|
*/
|
|
fun createFile(filePath: String, fileName: String): Boolean {
|
|
val strFilePath = filePath + fileName
|
|
|
|
val file = File(filePath)
|
|
if (!file.exists()) {
|
|
/** 注意这里是 mkdirs()方法 可以创建多个文件夹 */
|
|
file.mkdirs()
|
|
}
|
|
|
|
val subfile = File(strFilePath)
|
|
|
|
if (!subfile.exists()) {
|
|
try {
|
|
val b = subfile.createNewFile()
|
|
return b
|
|
} catch (e: IOException) {
|
|
e.printStackTrace()
|
|
}
|
|
} else {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* 遍历文件夹下的文件
|
|
*
|
|
* @param file 地址
|
|
*/
|
|
fun getFile(file: File): List<File>? {
|
|
val list: MutableList<File> = mutableListOf()
|
|
val fileArray = file.listFiles()
|
|
if (fileArray == null) {
|
|
return null
|
|
} else {
|
|
for (f in fileArray) {
|
|
if (f.isFile) {
|
|
list.add(0, f)
|
|
} else {
|
|
getFile(f)
|
|
}
|
|
}
|
|
}
|
|
return list
|
|
}
|
|
|
|
/**
|
|
* 删除文件
|
|
*
|
|
* @param filePath 文件地址
|
|
* @return
|
|
*/
|
|
fun deleteFiles(filePath: String): Boolean {
|
|
val files = getFile(File(filePath))
|
|
if (files!!.size != 0) {
|
|
for (i in files.indices) {
|
|
val file = files[i]
|
|
|
|
/** 如果是文件则删除 如果都删除可不必判断 */
|
|
if (file.isFile) {
|
|
file.delete()
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
//删除文件夹和文件夹里面的文件
|
|
fun deleteDirWihtFile(dir: File?) {
|
|
if (dir == null || !dir.exists() || !dir.isDirectory) return
|
|
for (file in dir.listFiles()) {
|
|
if (file.isFile) file.delete() // 删除所有文件
|
|
else if (file.isDirectory) deleteDirWihtFile(file) // 递规的方式删除文件夹
|
|
}
|
|
dir.delete() // 删除目录本身
|
|
}
|
|
|
|
|
|
/**
|
|
* 向文件中添加内容
|
|
*
|
|
* @param strcontent 内容
|
|
* @param filePath 地址
|
|
* @param fileName 文件名
|
|
*/
|
|
fun writeToFile(strcontent: String, filePath: String, fileName: String) {
|
|
//生成文件夹之后,再生成文件,不然会出错
|
|
val strFilePath = filePath + fileName
|
|
|
|
// 每次写入时,都换行写
|
|
val subfile = File(strFilePath)
|
|
|
|
|
|
var raf: RandomAccessFile? = null
|
|
try {
|
|
/** 构造函数 第二个是读写方式 */
|
|
raf = RandomAccessFile(subfile, "rw")
|
|
/** 将记录指针移动到该文件的最后 */
|
|
raf.seek(subfile.length())
|
|
/** 向文件末尾追加内容 */
|
|
raf.write(strcontent.toByteArray())
|
|
|
|
raf.close()
|
|
} catch (e: IOException) {
|
|
e.printStackTrace()
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 修改文件内容(覆盖或者添加)
|
|
*
|
|
* @param path 文件地址
|
|
* @param content 覆盖内容
|
|
* @param append 指定了写入的方式,是覆盖写还是追加写(true=追加)(false=覆盖)
|
|
*/
|
|
fun modifyFile(path: String?, content: String?, append: Boolean) {
|
|
try {
|
|
val fileWriter = FileWriter(path, append)
|
|
val writer = BufferedWriter(fileWriter)
|
|
writer.append(content)
|
|
writer.flush()
|
|
writer.close()
|
|
} catch (e: IOException) {
|
|
e.printStackTrace()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 读取文件内容
|
|
*
|
|
* @param filePath 地址
|
|
* @param filename 名称
|
|
* @return 返回内容
|
|
*/
|
|
fun getString(filePath: String, filename: String): String {
|
|
var inputStream: FileInputStream? = null
|
|
try {
|
|
inputStream = FileInputStream(File(filePath + filename))
|
|
} catch (e: FileNotFoundException) {
|
|
e.printStackTrace()
|
|
}
|
|
var inputStreamReader: InputStreamReader? = null
|
|
try {
|
|
inputStreamReader = InputStreamReader(inputStream, "UTF-8")
|
|
} catch (e1: UnsupportedEncodingException) {
|
|
e1.printStackTrace()
|
|
}
|
|
val reader = BufferedReader(inputStreamReader)
|
|
val sb = StringBuffer("")
|
|
var line: String?
|
|
try {
|
|
while ((reader.readLine().also { line = it }) != null) {
|
|
sb.append(line)
|
|
sb.append("\n")
|
|
}
|
|
} catch (e: IOException) {
|
|
e.printStackTrace()
|
|
}
|
|
return sb.toString()
|
|
}
|
|
|
|
/**
|
|
* 重命名文件
|
|
*
|
|
* @param oldPath 原来的文件地址
|
|
* @param newPath 新的文件地址
|
|
*/
|
|
fun renameFile(oldPath: String, newPath: String) {
|
|
val oleFile = File(oldPath)
|
|
val newFile = File(newPath)
|
|
//执行重命名
|
|
oleFile.renameTo(newFile)
|
|
}
|
|
|
|
|
|
/**
|
|
* 复制文件
|
|
*
|
|
* @param fromFile 要复制的文件目录
|
|
* @param toFile 要粘贴的文件目录
|
|
* @return 是否复制成功
|
|
*/
|
|
fun copy(fromFile: String, toFile: String): Boolean {
|
|
//要复制的文件目录
|
|
val currentFiles: Array<File>
|
|
val root = File(fromFile)
|
|
//如同判断SD卡是否存在或者文件是否存在
|
|
//如果不存在则 return出去
|
|
if (!root.exists()) {
|
|
return false
|
|
}
|
|
//如果存在则获取当前目录下的全部文件 填充数组
|
|
currentFiles = root.listFiles()
|
|
|
|
//目标目录
|
|
val targetDir = File(toFile)
|
|
//创建目录
|
|
if (!targetDir.exists()) {
|
|
targetDir.mkdirs()
|
|
}
|
|
//遍历要复制该目录下的全部文件
|
|
for (i in currentFiles.indices) {
|
|
if (currentFiles[i].isDirectory) //如果当前项为子目录 进行递归
|
|
{
|
|
copy(currentFiles[i].path + "/", toFile + currentFiles[i].name + "/")
|
|
} else //如果当前项为文件则进行文件拷贝
|
|
{
|
|
CopySdcardFile(currentFiles[i].path, toFile + currentFiles[i].name)
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
|
|
//文件拷贝
|
|
//要复制的目录下的所有非子目录(文件夹)文件拷贝
|
|
fun CopySdcardFile(fromFile: String?, toFile: String?): Boolean {
|
|
try {
|
|
val fosfrom: InputStream = FileInputStream(fromFile)
|
|
val fosto: OutputStream = FileOutputStream(toFile)
|
|
val bt = ByteArray(1024)
|
|
var c: Int
|
|
while ((fosfrom.read(bt).also { c = it }) > 0) {
|
|
fosto.write(bt, 0, c)
|
|
}
|
|
fosfrom.close()
|
|
fosto.close()
|
|
return true
|
|
} catch (ex: Exception) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取目录下所有文件
|
|
* @param path 指定目录路径
|
|
* @return
|
|
*/
|
|
fun getFilesAllName(path: String): List<String>? {
|
|
val file = File(path)
|
|
val files = file.listFiles()
|
|
if (files == null) {
|
|
Log.e("error", "空目录")
|
|
return null
|
|
}
|
|
val s: MutableList<String> = ArrayList()
|
|
for (i in files.indices) {
|
|
s.add(files[i].absolutePath)
|
|
}
|
|
return s
|
|
}
|
|
|
|
|
|
/**
|
|
* 解压缩一个文件
|
|
*
|
|
* @param zipFile 压缩文件
|
|
* @param folderPath 解压缩的目标目录
|
|
* @return
|
|
* @throws IOException 当解压缩过程出错时抛出
|
|
*/
|
|
@Throws(IOException::class)
|
|
fun upZipFile(zipFile: File?, folderPath: String): ArrayList<File> {
|
|
val fileList = ArrayList<File>()
|
|
val desDir = File(folderPath)
|
|
if (!desDir.exists()) {
|
|
desDir.mkdirs()
|
|
}
|
|
val zf = ZipFile(zipFile)
|
|
val entries: Enumeration<*> = zf.entries()
|
|
while (entries.hasMoreElements()) {
|
|
val entry = entries.nextElement() as ZipEntry
|
|
if (entry.isDirectory) {
|
|
continue
|
|
}
|
|
val `is` = zf.getInputStream(entry)
|
|
var str = folderPath + File.separator + entry.name
|
|
str = String(str.toByteArray(charset("8859_1")), charset("UTF-8"))
|
|
val desFile = File(str)
|
|
if (!desFile.exists()) {
|
|
val fileParentDir = desFile.parentFile
|
|
if (!fileParentDir!!.exists()) {
|
|
fileParentDir.mkdirs()
|
|
}
|
|
desFile.createNewFile()
|
|
}
|
|
val os: OutputStream = FileOutputStream(desFile)
|
|
val buffer = ByteArray(BUFFER_SIZE)
|
|
var length: Int
|
|
while ((`is`.read(buffer).also { length = it }) > 0) {
|
|
os.write(buffer, 0, length)
|
|
}
|
|
os.flush()
|
|
os.close()
|
|
`is`.close()
|
|
fileList.add(desFile)
|
|
}
|
|
return fileList
|
|
}
|
|
|
|
|
|
//复制文件
|
|
@Throws(IOException::class)
|
|
fun copyFile(sourceFile: File?, targetFile: File?) {
|
|
// 新建文件输入流并对它进行缓冲
|
|
val input = FileInputStream(sourceFile)
|
|
val inBuff = BufferedInputStream(input)
|
|
|
|
// 新建文件输出流并对它进行缓冲
|
|
val output = FileOutputStream(targetFile)
|
|
val outBuff = BufferedOutputStream(output)
|
|
|
|
// 缓冲数组
|
|
val b = ByteArray(1024 * 5)
|
|
var len: Int
|
|
while ((inBuff.read(b).also { len = it }) != -1) {
|
|
outBuff.write(b, 0, len)
|
|
}
|
|
// 刷新此缓冲的输出流
|
|
outBuff.flush()
|
|
//关闭流
|
|
inBuff.close()
|
|
outBuff.close()
|
|
output.close()
|
|
input.close()
|
|
}
|
|
|
|
fun writePackageName(packageName: String) {
|
|
val file = File(
|
|
Environment.getExternalStorageDirectory(),
|
|
"script/packagesname.txt"
|
|
)
|
|
val parentDir = file.getParentFile()
|
|
if (parentDir != null && !parentDir.exists()) {
|
|
val dirsCreated = parentDir.mkdirs()
|
|
if (!dirsCreated) {
|
|
Log.e("FileWrite", "Failed to create directories: $parentDir")
|
|
return
|
|
}
|
|
}
|
|
LogUtils.d("TAG", "writePackageName: $packageName", null)
|
|
try {
|
|
BufferedOutputStream(
|
|
FileOutputStream(file)
|
|
).use { bos ->
|
|
bos.write(packageName.toByteArray(StandardCharsets.UTF_8))
|
|
bos.flush() // 确保数据写入磁盘
|
|
}
|
|
} catch (e: IOException) {
|
|
Log.e("FileWrite", "Failed to write package name: $packageName", e)
|
|
// 6. 可以考虑添加重试机制或通知用户
|
|
}
|
|
}
|
|
} |