昨天遇到一个问题,某台 Jenkins 服务从 Mac 移植到 Windows,不得不把之前的 shell 脚本用 bat 实现,回想以前也遇到过这种情况

文件操作是比较常用的场景,以前用对于的增、删、改、查的实现比较多,在此基础上可以再丰富些功能,那么想法转化成行动吧

需求点

设计和解决思路

部分实现类代码

/**
 * 设置筛选内容,过滤出包含筛选内容的行
 * @param fname 文件路径
 * @param filter
 * @return 包含筛选内容的所有行
 */
public String grep(String fname, String filter) {
    String find = "";
    String line;
    try {
        inputStream = new FileInputStream(fname);
        encode = EncodingDetect.getJavaEncode(fname);
        sc = new Scanner(inputStream, encode);
        while (sc.hasNextLine()) {
            line = sc.nextLine();
            if (line.contains(filter))
                find = find + line + System.getProperty("line.separator");
        }
    } catch (FileNotFoundException e) {
        find = "";
        e.printStackTrace();
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
            if (sc != null) {
                sc.close();
            }
        } catch (IOException e) {
            find = "";
            e.printStackTrace();
        }
    }
    return find.trim();
}

/**
 * 从文件末尾开始,按指定行数输出
 * @param fileName 文件路径
 * @param lines 行数
 * @return 符合条件的行
 */
public String tail(String fileName, int lines) {
    boolean findFirstNonBlankLine = false;
    String line;
    String content = "";
    RandomAccessFile rf = null;

    try {
        rf = new RandomAccessFile(fileName, "r");
        long len = rf.length();
        long start = rf.getFilePointer();
        long nextend = start + len - 1;
        rf.seek(nextend);
        int c = -1;
        while (nextend > start) {
            c = rf.read();
            if (c == '\n' || c == '\r') {
                line = rf.readLine();
                if (lines > 0) {
                    if (null == line || line.trim().isEmpty()) {
                        if (findFirstNonBlankLine) {
                            content = line + System.getProperty("line.separator") + content;
                            lines--;
                        } else {
                            continue;
                        }
                    } else {
                        content = line + System.getProperty("line.separator") + content;
                        findFirstNonBlankLine = true;
                        lines--;
                    }
                }
                nextend--;
            }
            nextend--;
            if (lines == 0)
                break;
            rf.seek(nextend);
            // 当文件指针退至文件开始处,输出第一行
            if (nextend == 0) {
                line = rf.readLine();
                content = line + System.getProperty("line.separator") + content;
                break;
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (rf != null) {
                rf.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return content.trim();
}

/**
 * 文件查询,按指定列指定条件查询
 * @param from 文件路径
 * @param where 查询条件的列标
 * @param condition 查询条件
 * @param column 查询的字段
 * @return 符合条件的查询结果
 */
public List<List<String>> select(String from, int where, String condition, int... column) {
    String line;
    String[] columnOfLine;
    List<String> unitList = null;
    List<List<String>> selectList = new ArrayList<List<String>>();
    try {
        inputStream = new FileInputStream(from);
        encode = EncodingDetect.getJavaEncode(from);
        sc = new Scanner(inputStream, encode);
        while (sc.hasNextLine()) {
            line = sc.nextLine();
            line = line.trim().replaceAll(" +", " ").replaceAll("\t+", " ");
            if (line.isEmpty()) {
                continue;
            }
            unitList = new ArrayList<String>();
            columnOfLine = line.split(" ");
            if (columnOfLine[where - 1].trim().equals(condition)) {
                if (null != column && column.length > 0) {
                    for (int i = 0; i < column.length; i++) {
                        unitList.add(columnOfLine[column[i] - 1].trim());
                    }
                } else {
                    for (int i = 0; i < columnOfLine.length; i++) {
                        unitList.add(columnOfLine[i].trim());
                    }
                }
                selectList.add(unitList);
            }
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
            if (sc != null) {
                sc.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return selectList;
}

作为一个插件,虽然还不够完善,但至少解决了我目前的需求。日常工作中,总会遇到这样那样的问题,如能总结经验教训,转化成有用的东西,何乐而不为,希望对大家有帮助。


↙↙↙阅读原文可查看相关链接,并与作者交流