dom4j读写xml的奇怪问题

package util;

import bean.RecentContent;
import java.io.FileWriter;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class RecentContentDao
{
private String filePath = "../data/RecentContent.xml";

public ArrayList selectAll()
{
ArrayList rcArrayList = new ArrayList();
try {
SAXReader reader = new SAXReader();
InputStream file = super.getClass().getResourceAsStream(this.filePath);
Document document = reader.read(file);
Element root = document.getRootElement();
for (Iterator i = root.elementIterator("内容"); i.hasNext(); ) {
Element content = (Element)i.next();
RecentContent rc = new RecentContent();
rc.setCid(content.elementText("编号"));
rc.setTitle(content.elementText("标题"));
rc.setDetail(content.elementText("详细"));
rc.setDate(content.elementText("时间"));
rc.setSample(content.elementText("简介"));
rcArrayList.add(rc);
}
file.close();
} catch (Exception e) {
e.printStackTrace();
}

return rcArrayList;

}

[color=red]public boolean updateContent(String cid, String title, String detail, String date, String sample) {
boolean success = false;
try {
XMLWriter writer = null;
URL url = super.getClass().getResource(this.filePath);
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK");

  SAXReader reader = new SAXReader();
  InputStream file = super.getClass().getResourceAsStream(this.filePath);
  Document document = reader.read(file);
  Element root = document.getRootElement();

  for (Iterator i = root.elementIterator("内容"); i.hasNext(); ) {
    Element content = (Element)i.next();
    if (!(content.attributeValue("cid").equals(cid))) break label216;
    content.selectSingleNode("标题").setText(title);
    content.selectSingleNode("详细").setText(detail);
    content.selectSingleNode("时间").setText(date);
    content.selectSingleNode("简介").setText(sample);
    writer = new XMLWriter(new FileWriter(url.getFile()), format);
    writer.write(document);
    writer.close();
    success = true;
    label216: break;
  }

  file.close();
} catch (Exception e) {
  e.printStackTrace();
}
return success;

}[/color]

public RecentContent selectByCid(String cid) {
RecentContent rc = null;
try {
SAXReader reader = new SAXReader();
InputStream file = super.getClass().getResourceAsStream(this.filePath);
Document document = reader.read(file);
Element root = document.getRootElement();
for (Iterator i = root.elementIterator("内容"); i.hasNext(); ) {
Element content = (Element)i.next();
if (!(content.attributeValue("cid").equals(cid))) break label155;
rc = new RecentContent();
rc.setCid(content.elementText("编号"));
rc.setTitle(content.elementText("标题"));
rc.setDetail(content.elementText("详细"));
rc.setDate(content.elementText("时间"));
label155: rc.setSample(content.elementText("简介"));
}

  file.close();
} catch (Exception e) {
  e.printStackTrace();
}
return rc;

}
}
上面这个代码中红色部分 第一次执行会修改RecentContent.xml 但是第二次执行修改之后会把第一次修改过的内容变回来。。。

不是说改写不了,是读不到改过的。

而是说,你改了之后,URL的方式再去读,是硬盘上的。
getResource方式,是JVM的缓存里的。

也就是为啥 Freemarker要支持两种模板读取方式classpath和file directory

label216: break;
label155: rc.setSample(content.elementText("简介"));

这两句代码说明此源代码为反编译的结果

说明此程序被做了代码混淆

楼主还是按照这个代码逻辑重新写吧

写要在读的stream关闭之后啊。

public boolean updateContent(String cid, String title, String detail, String date, String sample) {
boolean success = false;
XMLWriter writer = null;
InputStream file = null;
Document document = null;
URL url = super.getClass().getResource(this.filePath);

try {   

  SAXReader reader = new SAXReader(); 
  file = super.getClass().getResourceAsStream(this.filePath); 
  Document document = reader.read(file); 
} catch (Exception e) { 
  e.printStackTrace(); 
   return false;
}  finally {
  if (in!=null) { 
        try { file.close();} catch(Exception ine) {}
   }
}

OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK");
try {
Element root = document.getRootElement();
for (Iterator i = root.elementIterator("内容"); i.hasNext(); ) {
Element content = (Element)i.next();
if (!(content.attributeValue("cid").equals(cid))) break label216;
content.selectSingleNode("标题").setText(title);
content.selectSingleNode("详细").setText(detail);
content.selectSingleNode("时间").setText(date);
content.selectSingleNode("简介").setText(sample);

    success = true; 
    label216: break; 
  }         
   writer = new XMLWriter(new FileWriter(url.getFile()), format); 
    writer.write(document); 

// 原来代码为啥 close会在循环里面?
writer.close();

 } catch (Exception e) {
   e.printStackTrace();
   return false;
 } finally {
   if (writer!=null) {
    try {writer.close();} catch (Exception we) {}
    }

}
return success;
}
[code="java"]

[/code]

哦,理解错了。

本质原因 是楼主 的代码是使用classloader去取classpath的里的文件。
jvm对classpath里的文件会有缓存的。
除非你能通知jvm,这个文件有更新。

因此,一般不把需要运行时重新读取的文件放到classpath里读取。
除非固定不修改了。