用java模拟windows下的dir指令
来源:互联网 发布:广东中标数据科技 编辑:程序博客网 时间:2024/05/20 11:27
- 胡扯
- 功能实现列表
- 需求分析
- 指令功能了解
- 指令分类
- 指令组合功能
- 代码结构
- 整体结构
- 详细结结构
- 几个重要的类
- 具体实现
- 指令解析
- 选项a
- 选项o
- 基本代码结构
- 多重排序的原理
- 修饰类 -TWCA L Q AIL C
- 异常处理
- TestCommandTokenizer
胡扯
这是一个很久以前就写了的代码,一直懒于相关的文档说明,所以一直一拖再拖,拖了很久。这个版本的说明还是比较简单的,如果整个张开来说的话,其实可以说上不少内容的。具体的源码可以到我的个人github上下载:https://github.com/DoneSpeak/java_Dos_Dir。
功能实现列表
需求分析
指令功能了解
通过help dir指令,我们可以查看dir指令的相关参数很选项以及对应的功能。当然为了更好的理解指令的的使用,我们还需要到网上去搜一些相关的讲解资料以及自己动手实际操作一遍。
指令分类
为了更好的吃掉这一只大象,我们需要将其划分成更容易实现和理解的多个小部分。通过实际了解以及实际操作,我们可以将所有的选项划分如下:
此外,以上不同类型选项之间均为并列关系。
指令组合功能
通过个人的实际使用,我将需要实现的功能又总结如下:
特点描述多指令操作D:\TestFolder /a-h-r-s /s /d/w/x/n/oe-ns /l/t:wca/q 多种输入方式,且设置默认目录- 支持大小写 Java Dir /A:h /oS
- 无限定输入顺序 Java Dir /a /a:-h D:\TestFolder/o /n
- 多种分隔符 Java Dir /a,/a:-h;D:\TestFolder/o;/n
- 默认目录为user.home
- Java Dir D:\TestFolder /oesn
- Java Dir D:\TestFolder /osen
- Java Dir D:\TestFolder /ose-n
- 准确检索 Java Dir D:\TestFolder\tdd.txt /s
- 正则表达式检索 Java Dir “D:\TestFolder\*.txt”
Java Dir /ahr/–/os D:\TestFolder
Java Dir /?
代码结构
整体结构
指令输入主要包含三种信息:dir指令(包含选项)、检索目录或者文件。由于指令输入可以很长,比如:D:\TestFolder /a-h-r-s /s /d/w/x/n/oe-ns /l/t:wca/q,该指令中包含了很多的组合信息,所以第一步我们需要对指令进行解析,解析出指令及相关选项,目录或者文件,以及判断出目录或者文件的字符串是否为正则表达式。解析完成之后,按照分类以及选项之间的相互关系对指令进行筛选,排序和显示(显示中会包含修饰)。
详细结结构
代码需要运行在windows下的cmd界面中,所以输入的字符串为参数数组args[]。之后的流程是对以上整体结果进行细化。
在处理完成之后,我们在显示之前进行了一次修饰,由于需要考虑显示类型选项之间的互斥关系,以及一些其他的只对部分显示选项才有效,所显示过程还有如下的流程关系。
几个重要的类
具体实现
指令解析
CommandTokenizer. commandTokenizer(String[] source, CommandElements cmdE, ArrayList<SearchObject> searchObj)
指令解析主要由类CommandTokenizer的commandTokenizer方法实现。source为输入的指令字符串,参数cmdE和searchObj为解析之后结果。
选项a
重点:获取文件的属性
为了获取到文件的属性,我们会使用到java.io.File
,但是我们知道,该类能够获取到的文件属性非常的少,因而这里我们需要使用到java.nio.file.*
类。相关部分api 可以看java官网的文档 http://docs.oracle.com/javase/8/docs/api/ 或者自己查找相关资料。
选项o
重点:排序、多重排序
基本代码结构
如下仅展示部分代码,其他的排序处理方法也如此。
//Actions.actionO//如下代码中FileComparator_DirFFileL是一个继承了接口Comparator的类,该类规定文件及目录按照目录在文件前面的方式排序ArrayList<File> fileList = fileListList.get(0);FileComparator_DirFFileL fc = new FileComparator_DirFFileL();fileList.sort(fc);···class FileComparator_DirFFileL implements Comparator<File> { @Override public int compare(File f1, File f2) { if (f1.isDirectory() && f2.isDirectory()) return f1.compareTo(f2); else if (f1.isDirectory() && !f2.isDirectory()) return -1; else if (!f1.isDirectory() && f2.isDirectory()) return 1; else return f1.compareTo(f2); }}
多重排序的原理
不难注意到,我们这里有两个特别的数据结构ArrayList<ArrayList<File>>
和ArrayList<File>
,对应下图就是ArrayList<ArrayList<File>>
为绿色部分,而ArrayList<File>
对应蓝色部分。
我们以指令Java Dir D:\TestFolder /oes
为例:开始的时候,所有的文件没有进行任何规则的排序处理,所以我们可以理解为其所有的文件都是一样的,之后进行按照拓展名进行升序排序,这时候中间部分的每个蓝色的矩形,也就是一个的ArrayList<File>
。每个这样的矩形都是具有相同的拓展名。之后在按照大小进行升序排序,也就得到了更加密的小矩形,这时的每个小矩形都是具有相同的文件拓展名和相同的大小。通过这种巧妙的方式,我们就便可以在保障数据结构(保障相同的数据结构可以保障能够使用相类似的数据处理过程)的前提下实现多重排序。
排序操作的O选项代码如下,其中省略部分为结果相类似的其他排序操作。
public static ArrayList<File> actionO(CommandElements cmdE, ArrayList<ArrayList<File>> fileListList) throws IOException { //// isEmpty(没有) size=1(第一个为1,仅有/a) size>1(含有其他属性) n(名字) s(大小) e(扩展名) //// d(时间) g(组目录优先) 负数表示- if (cmdE.actionO.isEmpty()) { // 不排序 return fileListList.get(0); } if (cmdE.actionO.size() == 1) { // 只排 /0 ArrayList<File> fileList = fileListList.get(0); FileComparator_DirFFileL fc = new FileComparator_DirFFileL(); fileList.sort(fc); return fileList; } Iterator<Integer> iter = cmdE.actionO.iterator(); iter.next();// 删除第一个表示只有/o的元素 while (iter.hasNext()) { Comparator<File> fc; int action = iter.next(); switch (action) { case (int) 'n': case -(int) 'n':{ if(action == (int)'n') fc = new FileComparator_Name(); else fc = new FileComparator_ReName(); sortWithDifferentFC(fileListList, fc); ArrayList<ArrayList<File>> finalfll = new ArrayList<ArrayList<File>>(); Iterator<ArrayList<File>> aFIter = fileListList.iterator(); while (aFIter.hasNext()) { ArrayList<File> sameFile = new ArrayList<File>(); ArrayList<File> flist = aFIter.next(); Iterator<File> afi = flist.iterator(); File f1 = null; if(afi.hasNext()){ f1 = afi.next(); sameFile.add(f1); } while(afi.hasNext()){ //同名称的放到同一个数组中 ArrayList<File> blank = new ArrayList<File>(); File f2 = afi.next(); if(f1.getName().equals(f2.getName())){ sameFile.add(f2); f1 = f2; } else{ f1 = f2; finalfll.add(sameFile); sameFile=blank; sameFile.add(f1); } } finalfll.add(sameFile); } fileListList = finalfll; break; } ··· return fileList;}
排序规则结果继承类。
class FileComparator_ReName implements Comparator<File> { @Override public int compare(File f1, File f2) { if(f1.getName().equals(f2.getName())) return 1; return f2.compareTo(f1); }}
排序函数
public static void sortWithDifferentFC(ArrayList<ArrayList<File>> fileListList, Comparator<File> fc) { ArrayList<ArrayList<File>> tfll = new ArrayList<ArrayList<File>>(); Iterator<ArrayList<File>> aFIter = fileListList.iterator(); while (aFIter.hasNext()) { ArrayList<File> flist = aFIter.next(); flist.sort(fc); tfll.add(flist); } fileListList = tfll;}
修饰类 -/T[W、C、A] /L /Q /A[I、L] /C
重点:字符长的格式化
显示修饰中,部分选项需要获取一些属性或者对字符串进行格式化。
- 获取文件上次写入时间 /tw
- 获取文件创建时间 /tc
- 获取文件上次访问时间 /ta
- 获取文件所有者 /q
- 获取所有者
- 判断文件类型
- 数值格式化
- 消除拓展名
异常处理
重点:重载Exception类
//使用enum使得代码更加简洁enum ExceptionEnum { WrongParameter, WrongSwitch, ProgrammeMistack, PrintHelpInfo , GrammaticalMistake, IsCannotIdentifyDevice, FileCannotFind}@SuppressWarnings("serial")public class CommandException extends Exception{ String message; public CommandException(ExceptionEnum exEnum,String parameter){ if(exEnum.equals(ExceptionEnum.WrongSwitch)){ message = "无效开关 - \""+parameter+"\"。"; } else if(exEnum.equals(ExceptionEnum.WrongParameter)){ message = "参数格式不正确 - \""+parameter+"\"。"; } else if(exEnum.equals(ExceptionEnum.ProgrammeMistack)){ message = "开发者编程出错!"; } else if(exEnum.equals(ExceptionEnum.PrintHelpInfo)){ message = "···"; //这里省略了帮助的信息 } else if(exEnum.equals(ExceptionEnum.GrammaticalMistake)){ message = "文件名、目录名或卷标语法不正确。"; } else if(exEnum.equals(ExceptionEnum.IsCannotIdentifyDevice)){ message = "\""+parameter + "\" 是无法识别设备。"; } else if(exEnum.equals(ExceptionEnum.FileCannotFind)){ message = "找不到文件"; } } @Override public String getMessage(){ return message; }}
TestCommandTokenizer
由于我的程序主要依赖于CommandTokenizer处理的来的信息(包括dir指令,检索路径和检索文件名),因此CommandTokenizer的正确运行是我后续运行的保障,所以我专门写了这么一个含有主函数的类来检查我输入的内容经CommandTonizer处理后得到的信息是否正确。
举例如下:
searchObjext中的数据是:
1. 检索文件名(是正则表达式的已转为正则表达式),文件路径,文件名是否为正则表达式
2. actionA和actionO中是他们的属性,笑脸(在eclipse中是小方格)表示含有/A或 /O 这个指令。
- 用java模拟windows下的dir指令
- DIR:windows下获取目录及子目录文件名称的命令
- 用java编程模仿DOS下的dir命令,列出某个目录下的内容
- 用Java读取Windows的Command指令
- Windows下的实用指令
- windows CMD 命令下dir 命令
- windows CMD 命令下dir 命令
- dir under linux.Linux下的类dir程序.
- windows下的cmd指令大全
- 【网络】Windows下的ping指令
- windows下命令行使用的一些指令
- Symfony3在windows下的指令
- Windows下常用指令
- linux下的c 编程------dir scan
- linux下的c 编程------dir scan
- 仿cmd命令行下的dir
- linux下的DIR,dirent,stat
- Linux下ls与dir的区别
- 资源管理:caching模式
- 开题:EffectiveJava
- Treap=Tree+Heap! 各种BST大PK(模板)
- caffe源码深入学习1:caffe.cpp解析
- MVC,MVP 和 MVVM 的图示
- 用java模拟windows下的dir指令
- 数据结构3----线性表中链式结构的其他几种实现(霜之小刀)
- 并查集
- C# 坐标变换::
- Js数组的基本方法1
- 第十五章 String类
- hdoj1028
- 2、SQL Server:SQL利用Case When Then多条件判断SQL 语句
- Ubuntu14.04lts wifi连接不稳定问题