基於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();
            }
        }
    }

  這里根據實際情況,來設置緩沖區的大小。

  這樣就可以根據接口返回的內容,寫入文件到指定的路徑中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM