Java 对不同类型的数据文件的读写操作整合器[JSON,XML,CSV]-[经过设计模式改造](2020年寒假小目标03)
日期:2020.01.16
博客期:125
星期四
我想说想要构造这样一个通用文件读写器确实不容易,嗯~以后会添加更多的文件类型,先来熟悉一下文件内容样式:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beangroup> 3 <javabean> 4 <data name='code'>A001</data> 5 <data name='name'>张三</data> 6 </javabean> 7 </beangroup>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{ list:[ { code:"A001", name:"张三" } ] }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
code,name A001,张三
【此处预留给未来添加的文件类型】
我所需要的基本功能是对表型数据的读写,这一点对于CSV这一种标准表形式的文件来说,构造它轻而易举,也没什么难度!而对于JSON和XML来说很难,其实JSON和XML是可以相互转换的,或者说这二者可以等价,毕竟JSON对应属性和XML对应标签属性如出一辙!而XML的标签内部内容刚好对应JSON里的具体内容!
好了话不多说,赶紧加代码:
com.filedeal包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.filedeal; 2 3 import java.io.File; 4 5 import com.dblink.bean.BeanGroup; 6 7 public interface FileControler { 8 //---[set、get方法] 9 //设置文件信息 10 void setFile(File file); 11 //获取处理的文件信息 12 File getFile(); 13 //---[类与对象方法] 14 //释放 15 void free(); 16 //重新设置 17 void reset(); 18 //表型数据植入 19 public void setUnderprinted(BeanGroup bg); 20 //表型数据获取 21 public BeanGroup getUnderprinted(); 22 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.filedeal; 2 3 import com.dblink.bean.BeanGroup; 4 import com.dblink.bean.JavaBean; 5 import com.dblink.bean.ReadableTable; 6 import com.filedeal.csv.CSVFileDealer; 7 import com.filedeal.json.JSONFileDealer; 8 import com.filedeal.xml.XMLFileDealer; 9 10 @SuppressWarnings("unused") 11 public class FileControlerTest { 12 public static void main(String[] args) { 13 BeanGroup bg = new BeanGroup(); 14 JavaBean jb1 = new JavaBean(); 15 jb1.add("序号"); 16 jb1.add("名称"); 17 jb1.add("性别"); 18 JavaBean jb2 = new JavaBean(); 19 jb2.add(1); 20 jb2.add("张三"); 21 jb2.add("男"); 22 JavaBean jb3 = new JavaBean(); 23 jb3.add(2); 24 jb3.add("李四"); 25 jb3.add("女"); 26 bg.add(jb1); 27 bg.add(jb2); 28 bg.add(jb3); 29 ReadableTable rt = ReadableTable.parseReadableTable(bg); 30 //CSV测试 31 /* 32 CSVFileDealer csv = new CSVFileDealer("src/testFiles/art.csv"); 33 csv.setUnderprinted(bg); 34 csv.free(); 35 */ 36 //XML测试 37 /* 38 XMLFileDealer xml = new XMLFileDealer("src/testFiles/aleion.xml"); 39 xml.setUnderprinted(bg); 40 System.out.println(xml.getUnderprinted().toJSONArray()); 41 */ 42 //JSON测试 43 JSONFileDealer json = new JSONFileDealer("src/testFiles/alert.json"); 44 //json.setUnderprinted(bg); 45 //System.out.println(json.getUnderprinted()); 46 //json.setUnderprinted(rt,false); 47 System.out.println(json.getUnderprinted(false).cloName); 48 System.out.println(json.getUnderprinted(false).beans); 49 } 50 }
com.filedeal.csv包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.filedeal.csv; 2 3 import java.io.BufferedWriter; 4 import java.io.File; 5 import java.io.FileNotFoundException; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import java.io.OutputStreamWriter; 9 import java.io.PrintWriter; 10 import java.io.UnsupportedEncodingException; 11 import java.util.Scanner; 12 13 import com.dblink.bean.BeanGroup; 14 import com.dblink.bean.JavaBean; 15 import com.filedeal.FileControler; 16 17 public class CSVFileDealer implements FileControler { 18 protected File file; 19 @Override 20 public void setFile(File file) { 21 this.file = file; 22 } 23 @Override 24 public File getFile() { 25 return file; 26 } 27 @Override 28 public void free() { 29 // Do Nothing ... 30 } 31 @Override 32 public void reset() { 33 String name = this.file.getName(); 34 this.free(); 35 this.file = new File(name); 36 } 37 //---[数据处理] 38 //设置数据集合 39 @Override 40 public void setUnderprinted(BeanGroup bg) { 41 try { 42 if(!file.exists()) 43 return; 44 PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"GB2312"))); 45 int leng = bg.size(); 46 47 for(int i=0;i<leng;++i) 48 { 49 JavaBean jb = bg.get(i); 50 String str = ""; 51 52 int leng_s = jb.size(); 53 54 for(int j=0;j<leng_s;++j) 55 { 56 String tmp = jb.get(j).toString(); 57 if(j==0) 58 str += tmp; 59 else 60 str += ","+tmp; 61 } 62 63 pw.println(str); 64 } 65 66 pw.close(); 67 } catch (FileNotFoundException e) { 68 e.printStackTrace(); 69 } catch (UnsupportedEncodingException e) { 70 e.printStackTrace(); 71 } 72 } 73 //获取数据集合 74 @Override 75 public BeanGroup getUnderprinted(){ 76 BeanGroup bg = new BeanGroup(); 77 try { 78 if(!this.file.exists()) 79 return bg; 80 Scanner sc = new Scanner(this.file); 81 while(sc.hasNextLine()) 82 { 83 String str = sc.nextLine(); 84 String [] sg = str.split(","); 85 86 JavaBean jb = new JavaBean(); 87 88 int leng = sg.length; 89 90 for(int i=0;i<leng;++i) 91 { 92 String tmp = sg[i]; 93 jb.add(tmp); 94 } 95 96 bg.add(jb); 97 } 98 sc.close(); 99 } catch (FileNotFoundException e) { 100 e.printStackTrace(); 101 } 102 return bg; 103 } 104 //---[构造方法] 105 public CSVFileDealer(String filePath){ 106 super(); 107 this.file = new File(filePath); 108 if(!this.file.exists()) 109 { 110 try { 111 this.file.createNewFile(); 112 } catch (IOException e) { 113 e.printStackTrace(); 114 } 115 } 116 } 117 public CSVFileDealer(File file){ 118 super(); 119 this.file = file; 120 if(!this.file.exists()) 121 { 122 try { 123 this.file.createNewFile(); 124 } catch (IOException e) { 125 e.printStackTrace(); 126 } 127 } 128 } 129 }
com.filedeal.xml包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.filedeal.xml; 2 3 import java.io.BufferedWriter; 4 import java.io.File; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.OutputStreamWriter; 8 import java.io.PrintWriter; 9 import java.io.Writer; 10 import java.util.ArrayList; 11 import java.util.List; 12 13 import com.dblink.bean.BeanGroup; 14 import com.dblink.bean.JavaBean; 15 import com.dblink.bean.ReadableTable; 16 import com.filedeal.*; 17 18 import org.dom4j.Attribute; 19 import org.dom4j.Document; 20 import org.dom4j.DocumentException; 21 import org.dom4j.Element; 22 import org.dom4j.io.OutputFormat; 23 import org.dom4j.io.SAXReader; 24 import org.dom4j.io.XMLWriter; 25 26 @SuppressWarnings("unused") 27 public class XMLFileDealer implements FileControler{ 28 protected File file; 29 @Override 30 public void setFile(File file) { 31 this.file = file; 32 } 33 @Override 34 public File getFile() { 35 return file; 36 } 37 @Override 38 public void free() { 39 // Do Nothing ... 40 } 41 @Override 42 public void reset() { 43 String name = this.file.getName(); 44 this.free(); 45 this.file = new File(name); 46 } 47 @Override 48 public void setUnderprinted(BeanGroup bg) { 49 this.createFile(); 50 ReadableTable rt = ReadableTable.parseReadableTable(bg); 51 try { 52 //基本属性构造 53 SAXReader reader = new SAXReader(); 54 Document doc = reader.read(this.file); 55 Element root = doc.getRootElement(); 56 57 //表头构造 58 Element e_header = root.addElement("cloumn"); 59 60 int num_header = rt.cloName.size(); 61 62 for(int i=0;i<num_header;++i) 63 { 64 Element e = e_header.addElement("info"); 65 e.setText(rt.cloName.get(i).toString()); 66 } 67 68 //由BeanGroup构造数据 69 int leng = rt.beans.size(); 70 71 for(int i=0;i<leng;++i) 72 { 73 JavaBean jb = rt.beans.get(i); 74 Element e_body = root.addElement("javabean"); 75 int leng_s = jb.size(); 76 for(int j=0;j<leng_s;++j) 77 { 78 Element e = e_body.addElement("data"); 79 e.setText(jb.get(j).toString()); 80 } 81 } 82 83 // 创建输出流 84 Writer out = new PrintWriter(this.file, "utf-8"); 85 86 // 格式化 87 OutputFormat format = new OutputFormat("\t", true); 88 89 //去掉原来的空白(\t和换行和空格)! 90 format.setTrimText(true); 91 92 XMLWriter writer = new XMLWriter(out, format); 93 // 把document对象写到out流中。 94 writer.write(doc); 95 96 out.close(); 97 writer.close(); 98 99 } catch (DocumentException e) { 100 e.printStackTrace(); 101 } catch (IOException e) { 102 e.printStackTrace(); 103 } 104 } 105 @Override 106 public BeanGroup getUnderprinted() { 107 if(!file.exists()) 108 return null; 109 BeanGroup bg = new BeanGroup(); 110 try { 111 //基本属性构造 112 SAXReader reader = new SAXReader(); 113 Document doc = reader.read(this.file); 114 Element root = doc.getRootElement(); 115 116 //表头构造部分 117 Element es = root.element("cloumn"); 118 List<Element> plist = es.elements("info"); 119 int num_l = plist.size(); 120 JavaBean jb_header = new JavaBean(); 121 for(int i=0;i<num_l;++i) 122 { 123 jb_header.add(plist.get(i).getText()); 124 } 125 bg.add(jb_header); 126 127 //表内数据构造部分 128 List <Element> rd = root.elements("javabean"); 129 int leng = rd.size(); 130 for(int i=0;i<leng;++i) 131 { 132 JavaBean jb = new JavaBean(); 133 Element e = rd.get(i); 134 List<Element> list = e.elements("data"); 135 int leng_s = list.size(); 136 137 for(int j=0;j<leng_s;++j) 138 { 139 jb.add(list.get(j).getText()); 140 } 141 bg.add(jb); 142 } 143 } catch (DocumentException e) { 144 e.printStackTrace(); 145 } 146 147 return bg; 148 } 149 public void createFile() { 150 this.createFile("beangroup"); 151 } 152 public void createFile(String rootName) { 153 if(this.file.exists()) 154 this.file.delete(); 155 try { 156 this.file.createNewFile(); 157 PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"GB2312"))); 158 pw.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 159 pw.println("<"+rootName+">"); 160 pw.println("</"+rootName+">"); 161 pw.close(); 162 } catch (IOException e) { 163 e.printStackTrace(); 164 } 165 } 166 //---[构造方法] 167 public XMLFileDealer(File file) { 168 super(); 169 this.file = file; 170 if(!this.file.exists()) 171 this.createFile(); 172 } 173 public XMLFileDealer(String filePath) { 174 super(); 175 this.file = new File(filePath); 176 if(!this.file.exists()) 177 this.createFile(); 178 } 179 }
com.filedeal.json包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.filedeal.json; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.OutputStream; 8 import java.text.ParseException; 9 import java.util.Scanner; 10 11 import org.json.JSONArray; 12 import org.json.JSONObject; 13 14 import com.dblink.bean.BeanGroup; 15 import com.dblink.bean.ReadableTable; 16 import com.filedeal.FileControler; 17 18 public class JSONFileDealer implements FileControler { 19 protected File file; 20 @Override 21 public void setFile(File file) { 22 this.file = file; 23 } 24 @Override 25 public File getFile() { 26 return file; 27 } 28 @Override 29 public void free() { 30 // Do Nothing ... 31 } 32 @Override 33 public void reset() { 34 String name = this.file.getName(); 35 this.free(); 36 this.file = new File(name); 37 } 38 @Override 39 public void setUnderprinted(BeanGroup bg) { 40 this.createFile(); 41 try { 42 OutputStream out = new FileOutputStream(this.file); 43 out.write(bg.toJSONArray().toString().getBytes()); 44 out.close(); 45 } catch (FileNotFoundException e) { 46 e.printStackTrace(); 47 } catch (IOException e) { 48 // TODO Auto-generated catch block 49 e.printStackTrace(); 50 } 51 } 52 @Override 53 public BeanGroup getUnderprinted() { 54 BeanGroup bg = null; 55 try { 56 String jarStr = ""; 57 Scanner sc = new Scanner(this.file); 58 while(sc.hasNextLine()) 59 { 60 jarStr += sc.nextLine(); 61 } 62 JSONArray jsonArray = new JSONArray(jarStr); 63 bg = BeanGroup.parseJSONArray(jsonArray); 64 sc.close(); 65 } catch (FileNotFoundException e) { 66 e.printStackTrace(); 67 } catch (ParseException e) { 68 e.printStackTrace(); 69 } 70 return bg; 71 } 72 //---[面向ReadableTable的方法] 73 public void setUnderprinted(ReadableTable rt) { 74 setUnderprinted(rt,false); 75 } 76 public void setUnderprinted(ReadableTable rt,boolean isArray) { 77 this.createFile(); 78 try { 79 OutputStream out = new FileOutputStream(this.file); 80 if(isArray) 81 out.write(rt.toJSONArray().toString().getBytes()); 82 else 83 out.write(rt.toJSONObject().toString().getBytes()); 84 out.close(); 85 } catch (FileNotFoundException e) { 86 e.printStackTrace(); 87 } catch (IOException e) { 88 // TODO Auto-generated catch block 89 e.printStackTrace(); 90 } 91 } 92 public ReadableTable getUnderprinted(boolean isArray) { 93 ReadableTable rt = null; 94 95 try { 96 String jarStr = ""; 97 Scanner sc = new Scanner(this.file); 98 while(sc.hasNextLine()) 99 { 100 jarStr += sc.nextLine(); 101 } 102 if(isArray) 103 { 104 rt = ReadableTable.parseJSONArray(new JSONArray(jarStr)); 105 } 106 else 107 { 108 rt = ReadableTable.parseJSONObject(new JSONObject(jarStr)); 109 } 110 sc.close(); 111 } catch (FileNotFoundException e) { 112 e.printStackTrace(); 113 } catch (ParseException e) { 114 e.printStackTrace(); 115 } 116 117 return rt; 118 } 119 //---[其余方法] 120 public void createFile() { 121 if(this.file.exists()) 122 this.file.delete(); 123 try { 124 this.file.createNewFile(); 125 } catch (IOException e) { 126 e.printStackTrace(); 127 } 128 } 129 //---[构造方法] 130 public JSONFileDealer(File file) { 131 super(); 132 this.file = file; 133 if(!this.file.exists()) 134 { 135 try { 136 this.file.createNewFile(); 137 } catch (IOException e) { 138 e.printStackTrace(); 139 } 140 } 141 } 142 public JSONFileDealer(String filePath) { 143 super(); 144 this.file = new File(filePath); 145 if(!this.file.exists()) 146 { 147 try { 148 this.file.createNewFile(); 149 } catch (IOException e) { 150 e.printStackTrace(); 151 } 152 } 153 } 154 }
扩充的基本类型:(JavaBean,BeanGroup,ReadableTable)
com.dblink.bean包:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.dblink.bean; 2 3 import org.json.JSONArray; 4 5 import java.util.ArrayList; 6 import java.util.Collection; 7 8 public class JavaBean extends ArrayList<Object> { 9 /** 10 * 11 */ 12 private static final long serialVersionUID = -1272079633276217217L; 13 //---[方法区] 14 //构造方法 15 public JavaBean() { 16 super(); 17 } 18 public JavaBean(Collection<Object> c) { 19 super(c); 20 } 21 public JavaBean(int initialCapacity) { 22 super(initialCapacity); 23 } 24 //转化方法 25 public String toString(){ 26 return super.toString(); 27 } 28 public JSONArray toJSONArray(){ 29 JSONArray jsonArray = new JSONArray(); 30 int leng = super.size(); 31 for(int i=0;i<leng;++i){ 32 Object q = super.get(i); 33 jsonArray.put(q); 34 } 35 return jsonArray; 36 } 37 public static JavaBean parseJSONArray(JSONArray jsonArray) { 38 JavaBean jb = new JavaBean(); 39 int leng = jsonArray.length(); 40 for(int i=0;i<leng;++i) 41 { 42 jb.add(jsonArray.get(i)); 43 } 44 return jb; 45 } 46 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.dblink.bean; 2 3 import org.json.JSONArray; 4 5 import java.util.ArrayList; 6 import java.util.Collection; 7 8 public class BeanGroup extends ArrayList <JavaBean> { 9 /** 10 * 11 */ 12 private static final long serialVersionUID = -3232871941539102307L; 13 //---[方法区] 14 //构造方法 15 public BeanGroup(int initialCapacity) { 16 super(initialCapacity); 17 } 18 public BeanGroup() { 19 super(); 20 } 21 public BeanGroup(Collection<JavaBean> c) { 22 super(c); 23 } 24 //转化方法 25 public String toString(){ 26 return super.toString(); 27 } 28 public JSONArray toJSONArray(){ 29 JSONArray jsonArray = new JSONArray(); 30 int leng = super.size(); 31 for(int i=0;i<leng;++i){ 32 JavaBean jb = super.get(i); 33 jsonArray.put(jb.toJSONArray()); 34 } 35 return jsonArray; 36 } 37 public static BeanGroup parseJSONArray(JSONArray jsonArray) { 38 BeanGroup bg = new BeanGroup(); 39 int leng = jsonArray.length(); 40 for(int i=0;i<leng;++i) 41 { 42 bg.add(JavaBean.parseJSONArray(jsonArray.getJSONArray(i))); 43 } 44 return bg; 45 } 46 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.dblink.bean; 2 3 import org.json.JSONArray; 4 import org.json.JSONObject; 5 6 public class ReadableTable { 7 //---[属性成员] 8 //列名称集合 9 public JavaBean cloName; 10 //表格详细信息 11 public BeanGroup beans; 12 //---[方法成员] 13 /*转移方法*/ 14 public static ReadableTable parseReadableTable(BeanGroup bg) { 15 JavaBean jb = new JavaBean(); 16 jb.addAll(bg.get(0)); 17 BeanGroup bgs = new BeanGroup(); 18 for(int i=1;i<bg.size();++i) 19 { 20 bgs.add(bg.get(i)); 21 } 22 return new ReadableTable(jb,bgs); 23 } 24 /*构造方法*/ 25 public ReadableTable(){ 26 this.cloName = null; 27 this.beans = null; 28 } 29 public ReadableTable(JavaBean cloName,BeanGroup beans){ 30 this.cloName = cloName; 31 this.beans = beans; 32 } 33 /*格式转化*/ 34 public JSONObject toJSONObject(){ 35 JSONObject jsonObject = new JSONObject(); 36 jsonObject.put("Length",this.beans.size()); 37 jsonObject.put("Column",this.cloName.size()); 38 jsonObject.put("ColNames",this.cloName.toJSONArray()); 39 jsonObject.put("Beans",this.beans.toJSONArray()); 40 return jsonObject; 41 } 42 public JSONArray toJSONArray(){ 43 JSONArray jsonArray = new JSONArray(); 44 JSONObject jsonObject = new JSONObject(); 45 int leng = this.beans.size(); 46 int cloNum = this.cloName.size(); 47 jsonObject.put("Length",leng); 48 jsonObject.put("Column",cloNum); 49 jsonObject.put("ColNames",this.cloName.toJSONArray()); 50 jsonArray.put(jsonObject); 51 for (int i=0;i<leng;++i) 52 { 53 JSONObject jso = new JSONObject(); 54 JavaBean jb = this.beans.get(i); 55 for(int j=0;j<cloNum;++j) 56 { 57 Object obj = jb.get(j); 58 String name = this.cloName.get(j).toString(); 59 jso.put(name,obj); 60 } 61 jsonArray.put(jso); 62 } 63 return jsonArray; 64 } 65 public static ReadableTable parseJSONArray(JSONArray json) { 66 ReadableTable rt = new ReadableTable(); 67 JSONObject jsonObj = json.getJSONObject(0); 68 int length = Integer.parseInt(jsonObj.get("Length").toString()); 69 int column = Integer.parseInt(jsonObj.get("Column").toString()); 70 rt.cloName = JavaBean.parseJSONArray(jsonObj.getJSONArray("ColNames")); 71 rt.beans = new BeanGroup(); 72 for(int i = 0;i<length;++i) 73 { 74 JavaBean jb = new JavaBean(); 75 76 for(int j=0;j<column;++j) 77 { 78 jb.add(json.getJSONObject(i).get(rt.cloName.get(j).toString())); 79 } 80 81 rt.beans.add(jb); 82 } 83 return rt; 84 } 85 public static ReadableTable parseJSONObject(JSONObject json) { 86 ReadableTable rt = new ReadableTable(); 87 rt.cloName = JavaBean.parseJSONArray(json.getJSONArray("ColNames")); 88 rt.beans = BeanGroup.parseJSONArray(json.getJSONArray("Beans")); 89 return rt; 90 } 91 }
添加了JSONArray、JSONObject与上述类型之间的类型转换(实现双向)
【此处预留给未来添加的文件类型】
实现类图:
所用设计模式:
1、策略模式:我发现这个模式真好用,而且简单,而且好用,嗯!针对文件处理不同的文件类型采取不一样的策略
2、模板方法模式:文件的读写操作算是基本的模板方法!
3、代理模式:嗯~要想json和xml的数据源完成读写事先需要调用ReadableTable类的方法进行数据整理,这一部分方法被封装在代理类里面,也可以不做数据处理,这正是代理模式的初衷!
参考文献:
1、XML的写文件方法