zoukankan      html  css  js  c++  java
  • 基于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();
                }
            }
        }

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

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

  • 相关阅读:
    CodeForces 659F Polycarp and Hay
    CodeForces 713C Sonya and Problem Wihtout a Legend
    CodeForces 712D Memory and Scores
    CodeForces 689E Mike and Geometry Problem
    CodeForces 675D Tree Construction
    CodeForces 671A Recycling Bottles
    CodeForces 667C Reberland Linguistics
    CodeForces 672D Robin Hood
    CodeForces 675E Trains and Statistic
    CodeForces 676D Theseus and labyrinth
  • 原文地址:https://www.cnblogs.com/generalli2019/p/12247715.html
Copyright © 2011-2022 走看看