使用commons.cli实现MyCP

Commons.cli库

考虑到这次的任务是实现自己的命令行命令cp,我认为简单地使用args[]无法很好的完成需求。经过网上的一番搜索,我找到Commons.cli库可以较好地处理命令行传参,于是我打算借助这次机会顺便掌握以下更高级的命令行传参。
首先从官网下载jar包,然后导入IDEA

因为我也是第一次接触这个包,不太熟悉,这是一些参考链接:Java命令行参数解析使用 Apache Commons CLI 开发命令行工具示例,这是官方文档


最简单的使用需要以下类和方法

大概框架写出来是这样

public class MyCP {
    public static void main(String[] args) {
        // Create a Parser
        CommandLineParser parser = new DefaultParser();
        Option optiontx=new Option("tx","txt2bin",true,"Convert .txt to .bin");
        optiontx.setArgs(2);//设置“-tx”选项固定参数数量为2
        optiontx.setRequired(false);//“-tx”参数不是必选
        Option optionxt=new Option("xt","bin2txt",true,"Convert .bin to .txt");
        optionxt.setArgs(2);
        optionxt.setRequired(false);
        Options options = new Options();
        options.addOption(optiontx);
        options.addOption(optionxt);
        File srcfile,dstfile;
        try{
            // Parse the program arguments
            CommandLine commandLine = parser.parse(options, args);
            // Set the appropriate variables based on supplied options
            if(commandLine.hasOption("tx")) {
                
            } else if (commandLine.hasOption("xt")) {
                
            } else {
                
            }
        } catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

更多的操作可以去看文档

MyCP

要实现MyCP,具体的需求分析如下:

  • 没有参数时实现复制文件
    • 源文件必须为存在,目的文件可以是目录或文件
    • 目的文件为路径时,在目的路径创建与源文件同名的文件;若目的路径是源文件所在路径,则退出程序并打印“filename is the same file with filename”(未完全解决目的文件为源文件的情况,目前想到可以尝试文件锁,但是还没有实施)
    • 目的文件为文件名时,创建目的文件,内容为源文件的复制
  • 参数为“-tx”时,将源文件中的十进制数字复制到目的文件并转为二进制
  • 参数为“-xt”时,将源文件中的二进制数字复制到目的文件并转为十进制

具体代码参考码云链接,以上需求均已实现

测试代码

这次Junit较为复杂,因为测试的是main方法,所以在参考一些博客后使用这样的框架

    @Test
    public void testNoOpt() {
        String[] args1 = {"1.txt", "2.txt"};
        String[] args2 = {"1.txt", "src"};
        MyCP.main(args1);
        MyCP.main(args2);
        try{
            assertTrue();
            assertTrue();
        }catch (Exception e){
            System.out.println(e.getMessage());
            fail();
        }
    }

由因为测试时要测试复制出来的文件是否和源文件一样,所以在开始测试前需要初始化出源文件,这里使用@Before来进行预处理

    @Before
    public void init(){
        File file = new File("1.txt");
        File numFile = new File("number.txt");
        File binaryFile = new File("binary.bin");
        try{
            file.createNewFile();
            numFile.createNewFile();
            binaryFile.createNewFile();
            FileOutputStream output = new FileOutputStream(file);
            output.write("MyCP works perfectly!!".getBytes());
            output = new FileOutputStream(numFile);
            output.write("10 a 9".getBytes());
            output = new FileOutputStream(binaryFile);
            output.write("1111 10 1001".getBytes());
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }

具体代码见码云链接
由于这次时间比较紧迫,在本次的Junit测试中没有测试应该抛出的异常,但是我都通过直接运行的方式测试过了。这次Junit测试主要尝试以前没有试过的main方法测试和预处理。
最终测试结果如下

总结

其实像这样自己去学习新的东西,为了实现自己设定的需求,一步一步精益求精,遇到问题立刻着手去解决,一边做一边学习,这种学习方法我比较习惯。可能是因为还算感兴趣的原因,虽然已经很晚了,但是我还是想把自己的程序写完。其实现在我已经在思考为了这么一个小作业这么麻烦是不是有点吃力不讨好,但是不管怎么说,我已经付出了努力,哪怕写出来的东西幼稚让人笑话,这大概就是我在有限时间有限精力下能发挥的极限了。
最近因为打ctf比赛,很多本来可能做的个人项目,可以写的博客都没有写。我深刻感受到自己能力的有限,一方面ctf一窍不通,另一方面java赶不上来。不过我相信努力会有回报的,笨鸟先飞不是吗?我也恳请老师能指出我代码的不足或者走的方向有错,毕竟提高效率、及时总结纠错比蛮干有效多了。

posted @ 2019-04-28 22:59  MustaphaMond  阅读(170)  评论(0编辑  收藏  举报