目录
前言
之前写了有关于文件操作的代码,不过有全局变量这种不安全的因素存在,而且类与类之间关系较为复杂,类之间的功能不太统一,就有了现在的重置版本。
一、创建指令中心CommondLineTool
package kFile
import java.util.Scanner
/**
* 第一步,创建指令中心
*/
class CommondLineTool private constructor() :ICallBack{
companion object {
/**
* by lazy 懒加载
* 定义时不加载,使用时才加载
* 只会被加载一次
*/
val instance: CommondLineTool by lazy {
CommondLineTool()
}
}
//创建文件管理器对象
//接收回调的对象 实现接口的功能
private val fileManager = FileManager(this)
private val parse = CommondParser(fileManager)
fun start(){
println("欢迎使用爱疯18操作系统,请输入您的指令:")
while (true){
showTitle(fileManager.currentName)
readCommond()
}
}
private fun showTitle(str:String){
//先显示当前路径
print("[$str]# ")
}
//输入指令
private fun readCommond(){
//判断有没有空格,如果有且只有一个,就用cmd1存储空格前的字符串
// cmd2存储空格后面的字符串,其他不符合条件的就提示用户重新输入
val scanner = Scanner(System.`in`)
//trim()用于去除字符串两端的空白字符(空格、制表符、换行符等)
val cmd = scanner.nextLine().trim()
//是将 cmd 中的字符串按照空格进行分割,并返回一个字符串数组。
val parts = cmd.split(" ")
parse.judge(parts.size,cmd,parts)
}
override fun showInfo(str:String?) {
//实现相应功能
println(str)
}
}
二、指令分析中心CommondParser
package kFile
import kotlin.system.exitProcess
/**
* 逻辑中心
* 解析指令,然后去执行相应的操作
*/
class CommondParser(private val listener: FileManager){
fun judge(judges : Int,cmd : String,parts : List<String>){
when (judges){
1 -> {
when (cmd) {
"ls" -> listener.listFile()
"exit" -> exitProcess(-1)
"pwd" -> listener.showCurrentPath()
else -> println("输入的指令不对,请重新输入!")
}
}
2 -> {
val cmd1 = parts[0]
val cmd2 = parts[1]
if (cmd1 == "ls" && cmd2 == "-l") listener.listFileAndMemory()
else if (cmd1 == "mkdirs") listener.creatDirectory(cmd2)
else if (cmd1 == "mkdir") listener.creatFile(cmd2)
else if (cmd1 == "vim") listener.creatVim(cmd2)
else if (cmd1 == "cd" && cmd2 == ".." ) listener.cdBackFile()
else if (cmd1 == "cd") listener.cdFile(cmd2)
else if (cmd1 == "cat") listener.checkFile(cmd2)
else if (cmd1 == "rm") listener.delete(cmd2)
else println("输入的指令不对,请重新输入!")
}
3 -> {
val cmd1 = parts[0]
val cmd2 = parts[1]
val cmd3 = parts[2]
if (cmd1 == "mv") listener.move(cmd2, cmd3)
else if (cmd1 == "rn") listener.rename(cmd2, cmd3)
else if (cmd1 == "cp") listener.copy(cmd2, cmd3)
else println("输入的指令不对,请重新输入!")
}
else -> println("输入的指令不对,请重新输入!")
}
}
}
三、接口ICallBack
package kFile
interface ICallBack {
fun showInfo(str:String?)
}
四、文件命令处理中心FileManager
package kFile
import java.io.File
import java.io.IOException
import java.lang.String.format
import java.util.ArrayList
class FileManager(private val callback :ICallBack):ICommondListener{
//实时记录当前的位置
//记得这里得改为自己桌面的地址
private var currentPath :String = "C:/Users/汐风的游戏/OneDrive/桌面"
//获取当前目录名称
var currentName :String = "桌面"
private val paths : ArrayList<String> = arrayListOf()
override fun listFile() {
val file = File(currentPath)
file.list()?.forEach {
callback.showInfo(it)
}
}
override fun listFileAndMemory() {
val dir = File(currentPath)
dir.listFiles()?.forEach { file ->
val fileSizeInBytes = file.length()
val fileSizeInMB = fileSizeInBytes.toDouble() / (1024 * 1024)
// 使用字符串格式化 "%.3f" 来保留小数点后三位
val show :String ="${file.name} ${format("%.3f",fileSizeInMB)} MB"
callback.showInfo(show)
}
}
override fun showCurrentPath() {
callback.showInfo(currentPath)
}
override fun creatDirectory(name:String) {
val dir = File(currentPath,name)
if(dir.mkdirs()){
callback.showInfo("创建成功")
}else callback.showInfo("创建失败")
}
override fun creatFile(name: String) {
val dir = File("$currentPath/$name")
if(dir.mkdir()){
callback.showInfo("创建成功")
}else callback.showInfo("创建失败")
}
override fun creatVim(name: String) {
val dir = File(currentPath,name)
if(dir.createNewFile()){
callback.showInfo("创建成功")
}else callback.showInfo("创建失败")
}
override fun cdFile(name: String) {
paths.add(name)
currentPath = "$currentPath/$name"
currentName = "$currentName/$name"
}
override fun cdBackFile() {
//判断是否为空
if(paths.isNotEmpty()){
val len = paths[paths.size-1].length + 1
val thisPath = removeLastNChars(currentPath, len)
val thisName = removeLastNChars(currentName, len)
currentPath = thisPath
currentName = thisName
paths.remove(paths[paths.size-1])
}
}
override fun checkFile(name: String) {
val dir = File(currentPath,name)
// 检查文件是否存在
if (dir.exists()) {
// 读取文件内容并打印到控制台
val text = dir.readText()
callback.showInfo(text)
}else callback.showInfo("该文件不存在")
}
override fun delete(name: String) {
val file = File(currentPath,name)
if(file.exists()) {
if(deleteDirectory(file)) callback.showInfo(" 删除成功")
else callback.showInfo(" 删除失败")
}
else callback.showInfo(" 该文件不存在")
}
//使用递归的方法来删除
private fun deleteDirectory(directory: File): Boolean {
if (directory.exists()) {
directory.listFiles()?.forEach { file ->
if (file.isDirectory) {
deleteDirectory(file)
} else {
file.delete()
}
}
}
return directory.delete()
}
override fun move(src: String, dir: String) {
//源文件地址
val source = File(currentPath,src)
//目标文件地址
val dsetnationDir = File(currentPath,dir)
//移动后地址
val dest = File(dsetnationDir,src)
// 检查要重命名的文件是否存在
try {
// 调用 renameTo() 方法进行重命名或移动
if (source.renameTo(dest)) callback.showInfo("移动成功")
else callback.showInfo("移动失败")
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun rename(src: String, dir: String) {
//源文件地址
val source = File(currentPath,src)
//目标文件
val dest = File(currentPath,dir)
try {
// 调用 renameTo() 方法进行重命名或移动
if (source.renameTo(dest)) callback.showInfo("重命名成功")
else callback.showInfo("重命名失败")
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun copy(src: String, dir: String) {
val source = File(currentPath, src)
val destinationDir = File(currentPath, dir)
val result = File(destinationDir, src)
try {
// 复制文件
copyRecursively(source, result)
callback.showInfo("复制成功")
} catch (e: IOException) {
e.printStackTrace()
callback.showInfo("复制失败")
}
}
private fun copyRecursively(source: File, destination: File) {
if (source.isDirectory) {
if (!destination.exists()) {
destination.mkdirs()
}
source.listFiles()?.forEach { file ->
val destFile = File(destination, file.name)
copyRecursively(file, destFile)
}
} else {
source.copyTo(destination, overwrite = true)
}
}
private fun removeLastNChars(input: String, n: Int): String {
if (n >= input.length) {
return ""
}
return input.substring(0, input.length - n)
}
}
五、接口ICommondListener
package kFile
interface ICommondListener {
fun listFile()
fun listFileAndMemory()
fun showCurrentPath()
fun creatDirectory(name:String)
fun creatFile(name:String)
fun creatVim(name:String)
fun cdFile(name:String)
fun cdBackFile()
fun checkFile(name: String)
fun delete(name: String)
fun move(src: String,dir: String)
fun rename(src: String,dir: String)
fun copy(src: String,dir: String)
}
最后在启动start方法即可
package kFile
fun main() {
CommondLineTool.instance.start()
}