Java 文件拼接器
1. 功能描述: 实现指定目录下相同类型的文件拼接成一个文件, 拼接效果如代码所示.
涉及内容: 反射, io, 递归
1.1 xml 的拼接:
<!-- \pom.xml --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.c0.util</groupId> <artifactId>file-combind</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>file-combind</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.6</version> </dependency> </dependencies> </project> <!-- \src\main\java\config\config.xml --> <?xml version="1.0" encoding="UTF-8"?> <types> <type> <name>java</name> <encoding>UTF-8</encoding> <src>E:\20_Workspaces\WS1\file-combind</src> <des>D:\test</des> <prune>E:\20_Workspaces\WS1\file-combind</prune> <!-- 第一行会添加文件路径, 需要去掉路径中的部分内容 --> <exclude>E:\20_Workspaces\WS1\file-combind\target</exclude> <!-- 排除的文件夹, 多个文件夹以分号隔开吧 --> </type> <type> <name>xml</name> <encoding>UTF-8</encoding> <src>E:\20_Workspaces\WS1\file-combind</src> <des>D:\test</des> <prune>E:\20_Workspaces\WS1\file-combind</prune> <exclude>E:\20_Workspaces\WS1\file-combind\target</exclude> <!-- 排除的文件夹, 多个文件夹以分号隔开吧 --> </type> </types>
1.2 java 文件的拼接:
// \src\main\java\com\c0\bean\Type.java package com.c0.bean; /** * 类型 bean * @author liuxl * 2017年8月26日 上午10:24:36 */ public class Type { /** 类型名称 */ private String name; /** 编码名称 */ private String encoding; /** 需合并文件的源路劲 */ private String src; /** 合并之后保存的目标路劲 */ private String des; /** 文件绝对路劲中需要剔除的部分 */ private String prune; /** 需排除的文件夹 */ private String exclude; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEncoding() { return encoding; } public void setEncoding(String encoding) { this.encoding = encoding; } public String getSrc() { return src; } public void setSrc(String src) { this.src = src; } public String getDes() { return des; } public void setDes(String des) { this.des = des; } public String getPrune() { return prune; } public void setPrune(String prune) { this.prune = prune; } public String getExclude() { return exclude; } public void setExclude(String exclude) { this.exclude = exclude; } } // \src\main\java\com\c0\util\FileManager.java package com.c0.util; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; import com.c0.bean.Type; /** * 用于将多个相同类型的文件拼接成一个文件的工具 * @author liuxl 2017年8月26日 上午8:35:50 */ public class FileManager { public static TypeFactory typeFactory = new TypeFactory(); public static void main(String[] args) { FileManager fm = new FileManager(); fm.combine(); } /** * 拼接所有类型的文件 * * 2017年8月26日 下午3:50:36 */ public void combine() { List<Type> types = typeFactory.getTypes(); for (Type type : types) { combineByType(type); } } /** * 拼接单个类型的文件 * * @param t * 2017年8月26日 下午3:50:50 */ @SuppressWarnings({ "unchecked", "rawtypes" }) public void combineByType(Type t) { List<File> files = new ArrayList(); File outFile = new File(t.getDes() + "\\" + t.getName() + "File." + t.getName()); if(outFile.exists()){ outFile.delete(); } traverseDir(t.getSrc(), t, files); try { FileOutputStream fos = new FileOutputStream(outFile); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos)); for(File file : files){ FileInputStream fis = new FileInputStream(file); BufferedReader reader = new BufferedReader(new InputStreamReader(fis, t.getEncoding())); String line = null; String filePath = file.getAbsolutePath(); String comment = filePath; if(StringUtils.isNotBlank(t.getPrune())){ comment = filePath.replace(t.getPrune(), ""); } writer.write(getComment(comment, t.getName())); while((line = reader.readLine()) != null){ writer.write(line + "\n"); } reader.close(); fis.close(); } writer.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 获取目录下所有相同类型的文件, 排除不要的文件夹 * * @param dir * @param type * 2017年8月26日 下午3:51:58 */ private void traverseDir(String dir, final Type t, final List<File> files) { File directory = new File(dir); if (!directory.isDirectory()) { return; } directory.listFiles(new FileFilter() { public boolean accept(File pathname) { if (pathname.isDirectory()) { if (StringUtils.isNotBlank(t.getExclude()) && t.getExclude().contains(pathname.getAbsolutePath())) { return false; } traverseDir(pathname.getAbsolutePath(), t, files); } else { if (pathname.getAbsolutePath().endsWith(t.getName())) { files.add(pathname); } } return false; } }); } /** * 返回注释后的内容 * * @param content * @return * 2017年8月26日 下午5:06:44 */ private String getComment(String content, String type){ String result = null; switch (type) { case "java": result = "// " + content + "\n"; break; case "xml": case "jsp": result = "<!-- " + content + " -->\n"; break; default: break; } return result; } } // \src\main\java\com\c0\util\TypeFactory.java package com.c0.util; import java.io.InputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.c0.bean.Type; /** * 解析配置文件并生成类型列表 * * @author liuxl * 2017年8月26日 上午10:33:52 */ public class TypeFactory { @SuppressWarnings({ "unchecked", "rawtypes" }) private List<Type> types = new ArrayList(); public static void main( String[] args ) { TypeFactory tf = new TypeFactory(); } public TypeFactory(){ initTypes(); } /** * 根据配置文件初始化类型列表 * * 2017年8月26日 下午3:28:17 */ @SuppressWarnings("unchecked") public void initTypes(){ InputStream in = TypeFactory.class.getClassLoader().getResourceAsStream("config\\config.xml"); SAXReader sr = new SAXReader(); Document document = null; try { document = (Document)sr.read(in); } catch (DocumentException e) { e.printStackTrace(); } Element root = document.getRootElement(); for(Element type : (List<Element>)root.elements()){ Class cls = null; Type t = null; try { cls = Class.forName("com.c0.bean.Type"); t = (Type)cls.newInstance(); } catch (ReflectiveOperationException e1) { e1.printStackTrace(); return; } for(Element field : (List<Element>)type.elements()){ String fieldName = field.getName(); String fieldValue = field.getTextTrim(); try { if(StringUtils.isNotBlank(fieldValue)){ Field f = cls.getDeclaredField(fieldName); f.setAccessible(true); f.set(t, fieldValue); } } catch (ReflectiveOperationException e) { e.printStackTrace(); return ; } } types.add(t); } } public List<Type> getTypes(){ return types; } }