大量数据写入到xml文件中?

flalscjf 2009-04-06 11:25:27
用java 把数据库里的数据写入到xml, 数据量很大的 主表大概有3000W条数据。
在网上找了一些资料, 有 jdom, sax, dom4j, dom 等技术。
有人说dom4j好用,我就拿dom4j来写了简单的程序。
往xml里写入到20000多一点的数据,java.lang.OutOfMemoryError 错误。

麻烦以前做过这方面工作的高手可以指点指点我这个菜鸟。

求大家帮帮忙了。

不一定要用dom4j的 只要能做出来就可以了。

先谢谢大家了。
...全文
830 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
宁静-夏天 2010-07-07
  • 打赏
  • 举报
回复
引用
Document doc = dom4j jdom把一条记录data转化为dom结构


自己也可以自己封装dom结构,并转化为byte。
宁静-夏天 2010-07-07
  • 打赏
  • 举报
回复
记录 datas [3000万]

File xmlFile;

OutputStream xmlOut = new FileOutputStream(xmlFile);

xmlOut.write(root开始tag);

for(data:datas){
Document doc = dom4j jdom把一条记录data转化为dom结构
byte docBytes[] = 将doc结构转化为byte[]
xmlOut.write(docBytes);
xmlOut.write(换行);
}

xmlOut.write(root开始tag);
xusenjian 2010-07-07
  • 打赏
  • 举报
回复
无数次的验证
yuwenbao 2010-07-07
  • 打赏
  • 举报
回复
要先搞清楚你为什么会出现outmemory 是因为你对字符串操作的太多了,你最好是利用多线程+批处理的形式,即每个线程处理100-1000条数据,然后起那么两三个线程,去并发处理,处理完毕后,将处理的总数目返回,作为下次处理的起始位置,然后依次去做,这样的话,应该不会出现内存溢出了。
GG_wg 2010-07-06
  • 打赏
  • 举报
回复
可以这样啊:读数据按分页的方式读取,先把一部分数据,生成文件xml,以后分批处理,没处理完一部分释放下内存
chudu 2010-07-06
  • 打赏
  • 举报
回复
额,我也从数据库中到处过大量数据到xml,我是以一百条数据为单位往下xml中写,采用dom4j,大约4100万,为出现溢出,可以试试。也可以用普通写文件的方法写成xml格式,多大数据都可搞定。
chenhua1934 2010-07-06
  • 打赏
  • 举报
回复
只要是按照流的方式读取XML就不会出现内存溢出的问题,java中好像SAX是这样实现的吧,这对大数量处理是比较好的!
wx830 2009-04-13
  • 打赏
  • 举报
回复
以上方法可行或傻瓜式方法, 一字符串的形式去拼规定格式
beiouwolf 2009-04-12
  • 打赏
  • 举报
回复
jdom包
用sax方式来写
挨踢民工_0917 2009-04-11
  • 打赏
  • 举报
回复
以文件形式一条一条的写不要生成dom树。
挨踢民工_0917 2009-04-11
  • 打赏
  • 举报
回复
以文件形式一条一条的写不要生成dom树。
Defonds 2009-04-06
  • 打赏
  • 举报
回复
有人写过一个,源码可供参考下
package ctais.business.jczc.yhs.wfwzxxcx; 

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
* Title: SAX 方式解析 XML 文件
* Description:解决大文件报OutOfMemory的问题
* Company: ****
* @author: Pagecn
* @date: YYYY-MM-DD
*/
public class SAXApp extends DefaultHandler implements Serializable {
private String LableName = ""; // 节点名称
private String LableValue = ""; // 节点值
private HashMap hm = new HashMap(); // 临时保存数据
private List list = new ArrayList(); // 保存插入的SQL语句


/**
* 根据文件路径建立 SAX解析器
* @param uri
*/
public void parseURI(String uri) {
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
sp.parse(uri, this);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 开始遍历
* @throws SAXException
*/
public void startDocument() throws SAXException {
//System.out.println(" <?xml version=\"1.0\" encoding=\"GB2312\"?>");
}

/**
* 取开始节点名称
* @param namespaceURI
* @param localName
* @param rawName
* @param attrs
* @throws SAXException
*/
public void startElement(String namespaceURI, String localName, String rawName, Attributes attrs) throws SAXException {
LableName = rawName;
}

/**
* 取节点值
* @param ch
* @param start
* @param length
* @throws SAXException
*/
public void characters(char ch[], int start, int length) throws SAXException {

// 过滤回车LableValue.indexOf("\n") == -1
if (LableValue.indexOf("\n") != -1) {
LableValue = "";
}
// 处理节点值过长,出现分段读取的情况
if (LableName.equals("COL1") || LableName.equals("COL2") || LableName.equals("COL3")) {
LableValue += new String(ch, start, length);
LableValue.trim();
} else {
LableValue = new String(ch, start, length);
}
}

/**
* 取结束节点名称
* @param namespaceURI
* @param localName
* @param rawName
* @throws SAXException
*/
public void endElement(String namespaceURI, String localName, String rawName) throws SAXException {
try {
// 获得有用节点信息放入HashMap
if (!(rawName.equals("XX") || rawName.equals("ITEM"))) {
hm.put(rawName, LableValue.trim());
LableValue = "";
}
// 组装SQL
if (rawName.equals("ITEM")) {
list.add("INSERT INTO TAB_NAME (COL1,COL2,COL3)"
+ " VALUES("
+ "'" + hm.get("COL1") + "',"
+ "'" + hm.get("COL2") + "',"
+ "'" + hm.get("COL3") + "')");
hm.clear();
}
} catch (Exception e) {
e.getMessage();
}

}

/**
* 遍历结束
* @throws SAXException
*/
public void endDocument() throws SAXException {
Statement stmt = null;
Connection conn = null;
int initsize = 0;
int size = 100;
try {
// 获取数据库连接
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:SID", "USER", "PASSWORD");
stmt = conn.createStatement();
initsize = stmt.getFetchSize();
stmt.setFetchSize(size);

// 批量插入数据,提高存储效率
for (int i = 0; i < list.size(); i++) {
stmt.addBatch((String) list.get(i));
}
stmt.executeBatch();

// 关闭数据库句柄
stmt.setFetchSize(initsize);
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
try {
if (stmt != null) {
if (initsize != 0) {
stmt.setFetchSize(initsize);
}
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException ee) {
ee.printStackTrace();
}
}
}

/**
* 测试方法
* 处理过>100M的XML文件,顺利完成,不过这种方式比较适合格式比较整齐、单一的XML文件
*/
public static void main(String args[]) {
/*
<ROOT>
<XX>
<ITEM>
<COL1/>
<COL2/>
<COL3/>
</ITEM>
</XX>
</ROOT>
*/
SAXApp st = new SAXApp();
st.parseURI("C:\\test.xml");
st.parseURI("C:\\ykk2007.xml");
}
}
Defonds 2009-04-06
  • 打赏
  • 举报
回复
3000W。。。
还是用SAX吧,分段编译,不会有java.lang.OutOfMemoryError 错误
flalscjf 2009-04-06
  • 打赏
  • 举报
回复
是的,3000W+ 的数据。
Despereaux 2009-04-06
  • 打赏
  • 举报
回复
3000W条数据
Defonds 2009-04-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 flalscjf 的回复:]
这位大哥,上一段代码是把xml里的数据写入到数据库里的代码吧?
你那里还有没有把数据库里的数据导入到xml里的代码段啊?
[/Quote]
没有了。。。
如果加分,我可以帮你找找。。。
:)开玩笑的,真的没有了
flalscjf 2009-04-06
  • 打赏
  • 举报
回复
这位大哥,上一段代码是把xml里的数据写入到数据库里的代码吧?
你那里还有没有把数据库里的数据导入到xml里的代码段啊?

67,550

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧