如何利用java解析tar.gz压缩文件中xml文件
2023年7月3日发(作者:)
如何利⽤java解析压缩⽂件中xml⽂件应⽤场景在⼤数据的⼯作中,每天必不可少的就是和数据打交道,我们需要从我们的业务⽅将数据采集过来,然后根据我们的业务逻辑将数据解析并转换成我们所需要的格式!⼤数据分析往往数据量都是⾮常⼤的,⼀天⼏⼗T都是很正常,如果按正常的来采集的话,估计就是采集都要花费不少时间,最常⽤的⽅式就是将数据进⾏压缩之后再进⾏传输,这样的效率是⽐较⾼的,也节省了带宽资源!举⼀个简单的例⼦,我们的逻辑是xml原始⽂件先压缩成⼀个gz⽂件,再将上百个gz⽂件再⼆次压缩成⼀个⽂件!⼀个压缩⽂件的⼤⼩⼤概是200M,但是解压出来就差不多20G此篇⽂章就记录⼀下实现功能需求的过程!依赖 s commons-compress 1.5 实现代码import 4j;import hiveEntry;import hiveInputStream;import s;import ;import Factory;import .*;import putStream;@Slf4jpublic class FileUtils { private static final Logger LOGGER = ger(); public static void main(String[] args) { deCompressGZipFile("path1", "dir1"); } /** * Tar⽂件解压⽅法 * * @param tarGzFile 要解压的压缩⽂件名称(绝对路径名称) * @param destDir 解压后⽂件放置的路径名(绝对路径名称)当路径不存在,会⾃动创建 * @return 解压出的⽂件列表 */ public static void deCompressGZipFile(String tarGzFile, String destDir) { // 建⽴输出流,⽤于将从压缩⽂件中读出的⽂件流写⼊到磁盘 TarArchiveEntry entry = null; TarArchiveEntry[] subEntries = null; File subEntryFile = null; try (FileInputStream fis = new FileInputStream(tarGzFile); GZIPInputStream gis = new GZIPInputStream(fis); TarArchiveInputStream taris = new TarArchiveInputStream(gis);) { while ((entry = tTarEntry()) != null) { StringBuilder entryFileName = new StringBuilder(); (destDir).append(tor).append(e()); File entryFile = new File(ng()); if (ctory()) { if (!()) { (); } subEntries = ectoryEntries(); for (int i = 0; i < ; i++) { try (OutputStream out = new FileOutputStream(subEntryFile)) { subEntryFile = new File(entryFileName + tor + subEntries[i].getName()); (taris, out); } catch (Exception e) { ("deCompressing file failed:" + subEntries[i].getName() + "in" + tarGzFile); } } } else { checkFileExists(entryFile); OutputStream out = new FileOutputStream(entryFile); (taris, out); (); //如果是gz⽂件进⾏递归解压 if (e().endsWith(".gz")) { String namepath = olutePath(); compressGZ(namepath); } } } //如果需要刪除之前解压的gz⽂件,在这⾥进⾏ File dir = new File("dir1"); File[] files = les(); for (File f:files) { if (e().split(".").length==3){ (); } } } catch (Exception e) { ("decompress failed", e); } } /** * 解压GZ⽂件 * @param pwd */ public static void compressGZ(String pwd){ if (!getExtension(pwd).equalsIgnoreCase("gz")) { n("File name must have extension of ".gz""); (1); } GZIPInputStream in = null; try { in = new GZIPInputStream(new FileInputStream(pwd)); } catch(FileNotFoundException e) { n("File not found. " + pwd); (1); } catch (IOException e) { tackTrace(); } String outFileName = getFileName(pwd); FileOutputStream out = null; try { out = new FileOutputStream(outFileName); } catch (FileNotFoundException e) { n("Could not write to file. " + outFileName); (1); } try { byte[] buf = new byte[1024]; int len; while((len = (buf)) > 0) { (buf, 0, len); } (); (); } catch (IOException e) { tackTrace(); } } /** * Used to extract and return the extension of a given file. * @param f Incoming file to get the extension of * @return String
representing the extension of the incoming * file. */ public static String getExtension(String f) { String ext = ""; int i = dexOf('.'); if (i > 0 && i < () - 1) { ext = ing(i+1); } return ext; } /** * Used to extract the filename without its extension. * @param f Incoming file to get the filename * @return String
representing the filename without its * extension. */ public static String getFileName(String f) { String fname = ""; int i = dexOf('.'); if (i > 0 && i < () - 1) { fname = ing(0,i); } return fname; } public static void checkFileExists(File file) { //判断是否是⽬录 if (ctory()) { if (!()) { (); } } else { //判断⽗⽬录是否存在,如果不存在,则创建 if (entFile() != null && !entFile().exists()) { entFile().mkdirs(); } try { NewFile(); } catch (IOException e) { tackTrace(); } } }} 这样就实现了将⽂件中的xml原始⽂件全部解压出来!之后就可以将xml⽂件中的数据拿出来做解析和分析了!java解析xml⽂件的⽅式有多种,这⾥使⽤dom4j!!依赖 4j dom4j 2.1.3 实现代码import nt;import ntException;import t;import der;import ;import putStream;import ption;import ;/** * java DOM4j xml解析 */public class JavaXMLTest { public static void main(String[] args) throws IOException, DocumentException { SAXReader reader = new SAXReader(); Document xmlDocument = (new FileInputStream(new File(""))); //n(doc==null?"未读取到xml⽂件":"已读取到xml⽂件"); //获取根节点 Element rootElement = tElement(); //获取根节点下的直接⼦节点的个数和名字 List list = ts("fileHeader"); //n("根节点下有"+()+"直接⼦节点"); //获取根节点下 fileHeader节点得value值 for (Element elemet:list) { String reportTime = uteValue("reportTime"); String startTime = uteValue("startTime"); String endTime = uteValue("endTime"); } //获取根节点下所有得 ⼦节点 List list1 = ts("header"); //n("根节点下header有"+()+"直接⼦节点"); //由于只有⼀个节点所以取get(0) Element header = (0); //获取header节点得value值 String id = uteValue("id"); //n("id是"+id); //获取header节点下所有 measure 节点 Element measure = ts("measure").get(0); //获取measurement节点下 smr节点 Element sm = ts("sm").get(0); //获取smr节点的value值 String stringValue = ingValue(); //按照空格进⾏拆分 String[] objj = (" "); //n("stringvalue===="+stringValue); //List smlist = ts("obj"); //获取measure节点下所有的 obj 节点 List objlist = ts("obj"); //Map map = new HashMap(); //遍历所有 obj节点 for (Element ob:objectlist) { //n(); //获取所有 obj节点 下的 v 节点 List vlist = ts("v"); //遍历 v 节点 for (Element v:vlist) { //n("v得value值是"+ingValue()); //获取v节点的value值 String[] vv = ingValue().split(" "); //n(); StringBuilder sb = new StringBuilder(); for (int i=0;i<;i++){ (objj[i]+"="+vv[i]); } n(ng()); sb=null; } } }}
⾄此,利⽤java就完成了对⽂件的解压,并对xml原始⽂件进⾏数据解析这个⽅法对于⼩数据量是可以实现的!但是⼤数据都是基于分布式⽂件系统Hadoop构建的!我们的数据都是存储在hdfs上的,⽽且数据也⾮常⼤,这样解压⽂件写到本地⽂件系统中,再解析其中的数据上传⾄hdfs!同时也是要消耗带宽的!最终在测试的时候是不⾏的!这个⽅案就被否定了!
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1688383815a129890.html
评论列表(0条)