zoukankan      html  css  js  c++  java
  • Java 高级文件处理

    XML简介

    • XML基本概念

      • XML(eXtensible Markup Language)

      • 可扩展标记语言:意义+数据

      • 标签可自行定义,具有自我描述性

      • 纯文本表示,跨系统/平台/语言

      • W3C标准

    • 常规语法

      • 任何的起始标签都必须有一个结束标签

      • 简化写法,例如,可以写成

      • 大小写敏感

      • 每个文件都要有一个根元素

      • 标签必须按合适的顺序嵌套,不可错位

      • 所有的特性都必要有值,且在值的周围加上引号

      • 需要转义字符,如"<"需要用&lt;代替

        &lt; < 小于
        &gt; > 大于
        &amp; & 和号
        &apos; ' 单引号
        &quot; " 双引号
      • 注释:

    • XML扩展

      1. DTD(Document Type Definition)

        • 定义XML文档的结构
        • 使用一系列合法的元素来定义文档结构
        • 可嵌套在xml文档中,或者在xml中引用
      2. XML Shema(XSD,XML Schema Definition)

        • 定义XML文档的结构,DTD的继任者
        • 支持数据类型,可扩展,功能更完善、强大
        • 采用xml编写
      3. XSL

        • 扩展样式表语言(eXtensible Stylesheet Language)

        • XSL作用于XML,等同于CSS作用于HTML

        • 内容:

          XSLT:转换XML文档

          XPath:在XML文档中导航

          XSL-FO:格式化XML文档

    XML解析(DOM方法)

    • XML解析方法

      1. 树结构

        • DOM:Document Object Model 文档对象模型,擅长(小规模)读/写
      2. 流结构

        • SAX:Simple API for XML 流机制解释器(推模式),擅长读
        • Stax:The Streaming API for XML 流机制解释器(拉模式),擅长读
    • DOM是W3C处理XML的标准API

      处理方式是将XML整个作为类似树结构的方式读入内存中以便操作及解析,方便修改。

      解析大数据量的XML文件,会遇到内存修理及程序崩溃的风险。

    • DOM类

      • DocumentBulider解析类,parse方法
      • Node节点主方法,getChildNodes返回一个NodeList
      • NodeList节点列表,每个元素是一个Node
      • Document文档根节点
      • Element标签节点元素(每个标签都是标签节点)
      • Text节点(包含在XML元素内的,都算Text节点)
      • Attr节点(每个属性节点)
    • 示例

      public class DomReader {
          public static void main(String[] args) {
              recursiveTraverse();
              System.out.println("======分割线=======");
              traverseBySearch();
          }
      
          public static void recursiveTraverse() {
              try {
                  // 采用DOM解析xml文件
                  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                  DocumentBuilder db = dbf.newDocumentBuilder();
                  Document document = db.parse("user.xml");
      
                  // 获取所有的一级节点
                  NodeList usersList = document.getChildNodes();
                  System.out.println("The 1st level length:"+usersList.getLength());
      
                  for(int i=0;i<usersList.getLength();i++) {
                      Node users = usersList.item(i);
                      NodeList userList = users.getChildNodes();
                      System.out.println("The 2nd level length:"+userList.getLength());
      
                      for(int j=0;j<userList.getLength();j++) {
                          Node user = userList.item(j);
                          if (user.getNodeType() == Node.ELEMENT_NODE) {
                              NodeList metaList = user.getChildNodes();
                              System.out.println("The 3rd level length:"+metaList.getLength());
      
                              for (int k=0;k<metaList.getLength();k++) {
                                  Node meta = metaList.item(k);
                                  if (meta.getNodeType() == Node.ELEMENT_NODE) {
                                      System.out.println(meta.getNodeName()+":"+meta.getTextContent());
                                  }
                              }
      
                              System.out.println();
                          }
                      }
                  }
      
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          public static void traverseBySearch() {
              try {
                  // 采用DOM解析xml文件
                  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                  DocumentBuilder db = dbf.newDocumentBuilder();
                  Document document = db.parse("user.xml");
      
                  Element rootElement = document.getDocumentElement();
                  NodeList nodeList = rootElement.getElementsByTagName("name");
                  if (nodeList != null) {
                      for (int i=0;i<nodeList.getLength();i++) {
                          Element element = (Element) nodeList.item(i);
                          System.out.println(element.getNodeName()+"="+element.getTextContent());
                      }
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      
      public class DomWriter {
          public static void main(String[] args) {
              try {
                  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                  DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
      
                  // 创建一个Document节点
                  Document document = documentBuilder.newDocument();
                  if (document != null) {
                      Element docx = document.createElement("document");
                      Element element = document.createElement("element");
                      element.setAttribute("type","paragraph");
                      element.setAttribute("alignment","left");
      
                      Element object = document.createElement("object");
                      object.setAttribute("type","text");
      
                      Element text = document.createElement("text");
                      text.appendChild(document.createTextNode("abcdefg"));
                      Element bold = document.createElement("bold");
                      bold.appendChild(document.createTextNode("true"));
      
                      object.appendChild(text);
                      object.appendChild(bold);
                      element.appendChild(object);
                      docx.appendChild(element);
                      document.appendChild(docx);
      
                      TransformerFactory transformerFactory = TransformerFactory.newInstance();
                      Transformer transformer = transformerFactory.newTransformer();
                      DOMSource source = new DOMSource(document);
      
                      // 定义目标文件
                      File file = new File("dom_result.xml");
                      StreamResult result = new StreamResult(file);
      
                      //将xml内容写入到文件中
                      transformer.transform(source,result);
      
                      System.out.println("write xml file successfully");
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      

    XML解析(SAX方法)

    • Simple API for XML

      • 采用事件/流模型来解析XML文档,更快速、更轻量
      • 有选择的解析和访问,不像DOM加载整个文档,内存要求较低
      • SAX对XML文档的解析为一次性读取,不创建/不存储文档对象,很难同时访问文档中的多处数据
      • 推模型。当它每发现一个节点就引发一个事件,而我们需要编写这些事件的处理程序。关键类:DefaultHandler
      • SAX的五个回调方法:
        1. startDocument 文档开始解析;
        2. endDocument文档结束解析;
        3. startElement开始访问元素;
        4. endElement结束访问元素;
        5. characters访问元素正文
    • 示例

      public class SAXReader {
          public static void main(String[] args) throws SAXException, IOException {
              XMLReader parser = XMLReaderFactory.createXMLReader();
              BookHandler bookHandler = new BookHandler();
              parser.setContentHandler(bookHandler);
              parser.parse("books.xml");
              System.out.println(bookHandler.getNameList());
          }
      }
      
      class BookHandler extends DefaultHandler {
          private List<String> nameList;
          private boolean title = false;
      
          public List<String> getNameList() {
              return nameList;
          }
      
          @Override
          public void startDocument() throws SAXException {
              System.out.println("Start parsing document...");
              nameList = new ArrayList<String>();
          }
      
          @Override
          public void endDocument() throws SAXException {
              System.out.println("End");
          }
      
          @Override
          public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
              if (qName.equals("title")) {
                  title=true;
              }
          }
      
          @Override
          public void endElement(String uri, String localName, String qName) throws SAXException {
              if(title) {
                  title=false;
              }
          }
      
          @Override
          public void characters(char[] ch, int start, int length) throws SAXException {
              if(title) {
                  String bookTitle = new String(ch, start, length);
                  System.out.println("Book title: "+bookTitle);
                  nameList.add(bookTitle);
              }
          }
      }
      

    XML解析(Stax方法)

    • Streaming API for XML

      • 流模型中的拉模型
      • 在遍历文档时,会把感兴趣的部分从读拉取器中拉出,不需要引发事件,允许我们选择性地处理节点。这大大提高了灵活性,以及整体效率。
      • 两套处理API
        1. 基础指针的API,XMLStreamReader
        2. 基于迭代器的API,XMLEventReader
    • 示例

      public class StaxReader {
          public static void main(String[] args) {
              StaxReader.readByStream();
              System.out.println("======分割线======");
              StaxReader.readByEvent();
          }
      
          // 流模式
          public static void readByStream() {
              String xmlFile = "books.xml";
              XMLInputFactory factory = XMLInputFactory.newFactory();
              XMLStreamReader streamReader = null;
              try {
                  streamReader=factory.createXMLStreamReader(new FileReader(xmlFile));
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (XMLStreamException e) {
                  e.printStackTrace();
              }
      
              // 基于指针遍历
              try {
                  while (streamReader.hasNext()) {
                      int event = streamReader.next();
                      if (event== XMLStreamConstants.START_ELEMENT) {
                          if("title".equalsIgnoreCase(streamReader.getLocalName())) {
                              System.out.println("title:" + streamReader.getElementText());
                          }
                      }
                  }
                  streamReader.close();
              } catch (XMLStreamException e) {
                  e.printStackTrace();
              }
          }
      
          // 事件模式
          public static void readByEvent() {
              String xmlFile = "books.xml";
              XMLInputFactory factory = XMLInputFactory.newFactory();
              boolean titleFlag = false;
              try {
                  // 创建基于迭代器的事件读取器对象
                  XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(xmlFile));
      
                  // 遍历Event迭代器
                  while (eventReader.hasNext()) {
                      XMLEvent event=eventReader.nextEvent();
                      // 如果事件对象是元素的开始
                      if (event.isStartElement()) {
                          // 转换成开始元素事件对象
                          StartElement start = event.asStartElement();
      
                          // 打印元素标签的本地名称
                          String name = start.getName().getLocalPart();
                          // System.out.println(name);
                          if (name.equals("title")) {
                              titleFlag = true;
                              System.out.print("title:");
                          }
      
                          // 取得所有属性
                          Iterator attrs = start.getAttributes();
                          while (attrs.hasNext()) {
                              // 打印所有属性信息
                              Attribute attr = (Attribute)attrs.next();
                              // System.out.println(":"+attr.getName().getLocalPart()+"="+attr.getValue());
                          }
                          // System.out.println();
                      }
      
                      // 如果事件对象是正文
                      if (event.isCharacters()) {
                          String s = event.asCharacters().getData();
                          if (s !=null && s.trim().length()>0 && titleFlag) {
                              System.out.println(s.trim());
                          }
                      }
      
                      // 如果事件对象时元素的结束
                      if (event.isEndElement()) {
                          EndElement end = event.asEndElement();
                          String name = end.getName().getLocalPart();
                          if (name.equals("title")) {
                              titleFlag = false;
                          }
                      }
                  }
                  eventReader.close();
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (XMLStreamException e) {
                  e.printStackTrace();
              }
          }
      }
      

    Json简介及解析

    • JSON

      • JavaScript Object Notation, JS对象表示法
      • 是一种轻量级的数据交换格式
      • 类似XML,更小、更快、更易解析
      • 最早用于Javascript,容易解析,最后推广到全语言
      • 尽管使用Javascript语法,但是独立于编程语言
    • JSONObject和JSONArray

      • 名称/值对。如“firstName":"Jhon”
      • JSON对象:{'name':'Jo', 'email':'a@b.com'}
      • 数据在键值对中
      • 数据由逗号分隔
      • 花括号保存对象
    • JSON数组

      • 方括号保存数组

        [{'name':'Jo', 'email':'a@b.com'}, {'name':'Jo', 'email':'a@b.com'}]

    • Java的JSON处理

      • org.json:JSON官方推荐的解析类

        简单易用,通用性强,复杂功能欠缺

      • GSON:Google出品

        基于反射,可以实现JSON对象、JSON字符串和Java对象互转

      • Jackson:号称最快的JSON处理器

        简单易用,社区更新和发布速度比较快

    • JSON主要用途

      • JSON生成
      • JSON解析
      • JSON校验
      • 和Java Bean对象进行互解析
        • 具有一个无参的构造函数
        • 可以包括多个属性,所有属性都是private
        • 每个属性都有相应的Getter/Setter方法
        • Java Bean用于封装数据,又可称为POJO(Plain Old Java Object)
    • 示例

      org.json

      public class OrgJsonTest {
          public static void main(String[] args) {
              testJsonObject();
              System.out.println("======分割线======");
              testJsonFile();
          }
      
          public static void testJsonObject() {
              // 构造对象
              Person p = new Person();
              p.setName("Tom");
              p.setAge(20);
              p.setScores(Arrays.asList(60,70,80));
      
              // 构造JSONObject对象
              JSONObject obj = new JSONObject();
              obj.put("name",p.getName());
              obj.put("age",p.getAge());
              obj.put("scores",p.getScores());
      
              System.out.println(obj);
              System.out.println("name: "+obj.getString("name"));
              System.out.println("age: "+obj.getInt("age"));
              System.out.println("scores: "+obj.getJSONArray("scores"));
          }
      
          public static void testJsonFile() {
              File file = new File("books.json");
              try {
                  FileReader reader = new FileReader(file);
                  // 读取文件内容到JSONObject对象中
                  int fileLen = (int)file.length();
                  char[] chars = new char[fileLen];
                  reader.read(chars);
                  String s = String.valueOf(chars);
                  JSONObject jsonObject = new JSONObject(s);
      
                  // 开始解析JSONObject对象
                  JSONArray books = jsonObject.getJSONArray("books");
                  List<Book> bookList = new ArrayList<>();
      
                  for(Object book:books) {
                      // 获取单个JSONObject对象
                      JSONObject bookObject = (JSONObject)book;
                      Book book1 = new Book();
                      book1.setAuthor(bookObject.getString("author"));
                      book1.setYear(bookObject.getString("year"));
                      book1.setTitle(bookObject.getString("title"));
                      book1.setPrice(bookObject.getInt("price"));
                      book1.setCategory(bookObject.getString("category"));
                      bookList.add(book1);
                  }
      
                  for(Book book:bookList) {
                      System.out.println(book.getAuthor()+", "+book.getTitle());
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      

      Gson

      public class GsonTest {
          public static void main(String[] args) {
              testJsonObject();
              System.out.println("======分割线======");
              testJsonFile();
          }
      
          public static void testJsonObject() {
              //构造对象
              Person p = new Person();
              p.setName("Tom");
              p.setAge(20);
              p.setScores(Arrays.asList(60,70,80));
      
              //从Java对象到JSON字符串
              Gson gson = new Gson();
              String s = gson.toJson(p);
              System.out.println(s);
      
              //从JSON字符串到Java对象
              Person p2 = gson.fromJson(s, Person.class);
              System.out.println(p2.getName());
              System.out.println(p2.getAge());
              System.out.println(p2.getScores());
      
              //调用GSON的JsonObject
              JsonObject json = gson.toJsonTree(p).getAsJsonObject();
              System.out.println(json.get("name"));
              System.out.println(json.get("age"));
              System.out.println(json.get("scores"));
          }
      
          public static void testJsonFile() {
              Gson gson = new Gson();
              File file = new File("books2.json");
      
              try {
                  FileReader reader = new FileReader(file);
                  List<Book> books = gson.fromJson(reader,new TypeToken<List<Book>>(){}.getType());
                  for(Book book:books) {
                      System.out.println(book.getAuthor()+", "+book.getTitle());
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      

    JSON和XML比较

    • 都是数据交换格式,可读性强,可扩展性高
    • 大部分的情况下,JSON更具优势(编码简单,转换方便),而且JSON字符串长度一般小于XML,传输效率更高
    • XML更加注重标签和顺序
    • JSON会丢失顺序信息
  • 相关阅读:
    电脑发朋友圈神器?不是严格意义上的
    微信公众平台投票功能升级 可多渠道发布投票
    多客服功能终于也向所有微信认证的订阅号开放了
    微信电脑版-微信for windows客户端发布
    微信朋友圈广告的赢家是他们
    微信公众平台原创声明功能公测 自媒体原创保护的福音
    微信公众平台数据接口正式对所有认证公众号开放
    壕,微信6.1版发微信红包更方便了,我们去喝杯茶吧
    微信公开课发布微信官方教程:教你用好微信JS-SDK接口
    微信公众平台开放JS-SDK(微信内网页开发工具包)
  • 原文地址:https://www.cnblogs.com/hunter-w/p/13882336.html
Copyright © 2011-2022 走看看