• 基于Java+HttpClient+TestNG的接口自动化测试框架(八)------ 针对文件的处理


      在实际的接口测试中,有时需要根据情况进行文件的上传和下载。在文件数量比较小的时候,我们当然可以直接处理(比如若干个接口都用一个文件)。但是,如果我们上传的文件需要使用不同文件夹里不同的文件,而且数量又比较大的情况下,直接写路径就比较麻烦了。

      那么,怎样来处理这样的问题呢?还是需要先整理一下思路。

      首先,我们需要根据某些特征,找到这些文件。例如,我们可以在指定的文件夹下面,按照文件后缀名来找寻文件。通常,我们在DOS下查询该文件夹下寻找同一后缀名文件的时候,会使用通配符“*”来代替文件名,例如:*.jpg,*.xls等等。那么,我们可以指定一个文件夹,然后使用将通配符变为正则的方式,来匹配查找文件。

      另外,如果在我们指定的文件夹中,存在子文件夹的情况,我们需要进行递归处理。即,进入子文件夹后,再次对子文件夹下的对象进行遍历,以此类推。

    先来看一段代码:

        private static String generatePattern(String fileConf) {
            fileConf = fileConf.trim();
            // 根据配置生成正确的正则
            fileConf = fileConf.replace('*', '#');
            // 将*号之前加上.
            fileConf = fileConf.replaceAll("#", ".*");
            return fileConf;
        } 

      这里,我们定义了一个生成正则的方法。就是将"*.XXX"变成“.*.XXX”(仔细看,就是在之前加了一个".")。我们可以利用这个正则表达式来匹配我们想要寻找的文件。

      接下来,我们来看一下递归查找的问题。首先,我们需要定义一个要查找的文件夹。而在java中,我们可以直接定义一个主路径作为file的对象。

    例如:

            String c = "k:/abc/";
            File file = new File(c);

    这样的话,可以使用getName()方法获取文件或文件夹的名称(不包含上级路径)。另外,也可以使用listFiles() 返回目录下的文件或者目录对象(File类实例),包含隐藏文件。当然,对于文件,这样操作会返回null。

    下面,我们来看一下递归的操作。思路是这样的:

    1.判断当前的file对象是文件还是文件夹

    2.如果是文件,若匹配正则,则将文件加入list。

    3.如果是文件夹,则获取该文件夹下面所有的文件或者目录对象,若匹配正则,则将文件加入list。

        private static ArrayList<File> filePattern(File file, Pattern p) {
            if (file == null) {
                return null;
            }
            // 如果是文件,则加入fileList
            if (file.isFile()) {
                Matcher fMatcher = p.matcher(file.getName());
                if (fMatcher.matches()) {
                    ArrayList<File> list = new ArrayList<File>();
                    list.add(file);
                    return list;
                }
                // 如果是目录,则进行递归查找
            } else if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files != null && files.length > 0) {
                    ArrayList<File> list = new ArrayList<File>();
                    for (File f : files) {
                        //此处进行递归
                        ArrayList<File> rlist = filePattern(f, p);
                        if (rlist != null) {
                            //将查找结果都加入fileList
                            list.addAll(rlist);
                        }
                    }
                    return list;
                }
            }
            return null;
        }

      那么,根据上面的代码,我们可以将路径下所有的匹配正则的文件都找到,并放入fileList中。

      接下来,我们来定义一个方法,使用主路径以及通配符作为参数,来进行文件的查找。在通配符参数的指定中,我们使用“;”来进行分隔,来找到我们所需要的文件。

    例如:

    String dirs = "k:/abc/";
    String file_con = "*.doc;*.xls";

      这里会出现一个新的问题,如果我按照上面所写,会把“k:/abc/”下的所有匹配的文件都找出来。

      假如,我是需要寻找主路经下test1文件夹下的*.doc,和test2文件夹下的*.xls怎么办?

      这里在指定参数的部分,我们需要对文件夹作出判断,即对最后一个“/”进行分隔处理。

    请看下面一段代码:

        public static List<File> getFilesByConf(String dir, String fileConf) {
            String[] fileConfArr = fileConf.split(";");// 多个配置‘;’分开
            List<File> list = new ArrayList<File>();
            if (fileConfArr != null && fileConfArr.length > 0) {
                for (String conftemp : fileConfArr) {
                    int at = conftemp.lastIndexOf("/");
                    File file = null;
                    String fileContextPath = "";
                    // 绝对目录路径
                    String contextPath = dir;
                    // 针对目录部分的处理
                    if (at > 0) {
                        fileContextPath = fileConf.substring(0, at);
                    }
                    if (StringUtil.isNotEmpty(fileContextPath)) {
                        contextPath = contextPath + fileContextPath;
                    }
                    file = new File(contextPath);
                    String fileNameConf = conftemp.substring(at + 1,conftemp.length());// 文件名配置
                    String fileConfTemp = generatePattern(fileNameConf);
                    Pattern p = Pattern.compile(fileConfTemp);
                    ArrayList<File> listtemp = filePattern(file, p);
                    list.addAll(listtemp);
                }
            }
            return removeDuplicate(list);// 去重
        }

      这里,我们就完成了针对路径的处理。顺便说一下,这里的去重,使用的是利用HashSet的特性来进行去重。

        public static List removeDuplicate(List list) {
            if (list == null) {
                return null;
            }
            Set set = new HashSet();
            List newList = new ArrayList();
            for (Iterator iter = list.iterator(); iter.hasNext();) {
                Object obj = iter.next();
                if (set.add(obj)) {
                    newList.add(obj);
                }
            }
            return newList;
        }

      至此,我们就完成了对于文件查找的处理。

      总结一下,我们只需要提供两个参数,一个是主路经,一个匹配的通配符的字符串参数(可以带路径),即可批量查找到我们所需要的文件。

      

      接下来,我们看一下,下载文件的处理。

      下载文件一般比较好处理,基本思路就是使用输入流来写入,然后保存即可。

      需要注意的是,针对比较大的文件时,我们需要设置Buffer(即缓冲区)。不应用缓冲区的时候,每次读取一个字节,写入一个字节,由于操作磁盘比内存慢的很多,所以不应用缓冲区效率很低;应用缓冲区,可以一次读取多个字节,先不写入磁盘,而是放入内存之中,到了缓冲区大小的时候,在写入磁盘,减少了对磁盘的操作,效率较高。

    public static boolean writeFile(InputStream is, String filePath) {
            File file = new File(filePath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            FileOutputStream fileout;
            try {
                fileout = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return false;
            }
            /**
             * 根据实际运行效果 设置缓冲区大小
             */
            byte[] buffer = new byte[10 * 1024];
            int ch = 0;
            try {
                while ((ch = is.read(buffer)) != -1) {
                    fileout.write(buffer, 0, ch);
                }
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } finally {
                try {
                    is.close();
                    fileout.flush();
                    fileout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

      这里根据实际情况,来设置缓冲区的大小。

      这样就可以根据接口返回的内容,写入文件到指定的路径中。

  • 相关阅读:
    前端一站式学习地址
    springboot注解开发
    java中的四种内部类使用(1)
    java内存回收机制
    TweenMax详解
    flash渲染机制
    通过字符串名访问变量
    总结调用Flash的几种方法
    flex buider2 的注册
    转:FlexChn.Cn Adobe Flex最佳学习路线
  • 原文地址:https://www.cnblogs.com/generalli2019/p/12247715.html
Copyright © 2020-2023  润新知