用java读取大文件问题 用java读取大文件,一般都是内存溢出,比如读取大的xml文件,然后解析,,再举个例子,当导出的大数据文件.csv达100+,读取,解释,就会爆出内存溢出的问题,而我在用db2的时候,用他的自己的工具可以解决。不知道他的程序是用什么写的,java可以实现么?或者各位有什么经验与解决方案,希望能提出分享一下,谢谢。分不是问题。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 增加Java虚拟机内容的方式试试 -Xms256M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M 觉得这个问题你应该要换一种思路,JAVA读取大文件并没有问题,问题是你全部都读到内存中来了,肯定内存要溢出。你要做的其实就是按照sax的读取方式,用一部分读一部分,这样就不会有问题了。导出数据是一样的,你要采用流的方式,不要全部放在内存中,CSV文件可以动态生成的,不要全部生成了之后再导出来,读取的时候也一部分一部分的读取。 哎,这也是没有办法的事情,你看楼主说:“比如读取大的xml文件,然后解析”。还要分析XML。那可能要用到Dom4J或Jdom。那些都是需要直接加载到内存中的。sax自己去分析XML。太麻烦了吧 首先感谢各位。mayuanfei,增加参数,个人人为不是解决问题的关键,所谓治标不治本。lovingprince,这个思路非常不错,本人也考虑过,而且人为这条思路,是必然得,只不过在具体实践中,可能各有神通,并不容易。如你说的csv,动态生成等,应该可以。但如果我是一个一定结构性的大xml数据文件,需要解析,有没有可能溢出?具体的例子,导出一个大的SQL语句的xml,先是表结构DDL,然后是要插入的数据(假设如此,不考虑数据结构合理性)。要一次性的处理 ,我相信,如果是小文件,大家都可以做到。即便手工,拷贝出来,粘贴到SQL脚本执行框,也可执行。然而勇程序处理,一般方法还是解析而后执行。关键在于此,不知道类似c,c++是如何处理。 Dom解析xml文件本身就有占用内存问题的...加大内存或者改用其它方式来做吧! 用RandomAccessFile读取就好了,不会一次性全部读出,而是一次一小段public class A { public static void main(String[] args) { try { long start = Runtime.getRuntime().freeMemory(); RandomAccessFile rF = new RandomAccessFile("D:/abc.zip", "r"); for (int i = 0; i < 100; i++) { if ((i % 16) == 0) System.out.print("\r\n"); System.out.print(Functions.getByteHexStr(rF.readByte()) + " "); } long end = Runtime.getRuntime().freeMemory(); System.out.println("\n\nused menory:" + (start - end) / 1024 + "KB"); rF.close(); } catch (Exception e) { e.printStackTrace(); } }} 无论你用C还是C++,都不可能将所有东西都放入内存中处理,这个是不可能的。无论是DB2的导出工具还是其它的,都肯定是读取一部分然后写一部分,不可能都读入内存的(如果都读入内存,那数据库还要来做什么,全部内存存储得了) 如果是这么大的文件话,我们是不是可以换个思路。把它转换成Bean存入到数据库中。节点的查询,换成是数据库的SQL语句。 任何解析工具都支持 Stream 的方式,去看看API吧。 的确比较麻烦,如果是XML文件的话,我觉得可以先建立索引,再根据索引分段读取文件 因为XML结构化比较好啊所以可以用一个B-树的结构把其所有标签起始/结尾的位置做成索引然后要读取时根据这个B-树来分段读取理论上是这样 分解文件也是一个途径,总体来看,读取一部分,解析一部分是方向。zapdos,能给个实际代码例子么? 我没有做过,这只是一个设想而已根据JAVA的特点,要做这个应该没问题的 理论上要用B-树建立索引也是很容易的因为XML都有一个开,一个关的标记,开的话就添加节点,关的话就回溯一层,顺序读一次就可以建立索引了 太大的文件还是用SAX吧,DOM是把文件全部读进来,SAX是部分读进来。 good,谢谢,不能再加分,故结贴! 请教大侠为什么这里会抛arraystroeExcepion异常 请教抽象类和抽象方法的具体应用 使用pl/sql树形查询后,如果封装成json类型? Java中的参数都是传值,那怎么交换两个变量的值呢。 java.sql.SQLException: Value conflicts occurs ArrayList是不是一能存不同数据类型的数组? 关于Object比较 求助,list去重问题 Form2如何访问Form1的变量? 请问哪有weblogic的设置中文资料 刚入手JAVA求问关于数组问题 请问关于GUI里的TextField问题
mayuanfei,增加参数,个人人为不是解决问题的关键,所谓治标不治本。
lovingprince,这个思路非常不错,本人也考虑过,而且人为这条思路,是必然得,只不过在具体实践中,可能各有神通,并不容易。
如你说的csv,动态生成等,应该可以。但如果我是一个一定结构性的大xml数据文件,需要解析,有没有可能溢出?具体的例子,导出一个大的SQL语句的xml,先是表结构DDL,然后是要插入的数据(假设如此,不考虑数据结构合理性)。要一次性的处理 ,我相信,如果是小文件,大家都可以做到。即便手工,拷贝出来,粘贴到SQL脚本执行框,也可执行。然而勇程序处理,一般方法还是解析而后执行。
关键在于此,不知道类似c,c++是如何处理。
Dom解析xml文件本身就有占用内存问题的...加大内存或者改用其它方式来做吧!
public class A {
public static void main(String[] args) {
try {
long start = Runtime.getRuntime().freeMemory();
RandomAccessFile rF = new RandomAccessFile("D:/abc.zip", "r");
for (int i = 0; i < 100; i++) {
if ((i % 16) == 0)
System.out.print("\r\n");
System.out.print(Functions.getByteHexStr(rF.readByte()) + " ");
}
long end = Runtime.getRuntime().freeMemory();
System.out.println("\n\nused menory:" + (start - end) / 1024 + "KB");
rF.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
无论是DB2的导出工具还是其它的,都肯定是读取一部分然后写一部分,不可能都读入内存的(如果都读入内存,那数据库还要来做什么,全部内存存储得了)
所以可以用一个B-树的结构把其所有标签起始/结尾的位置做成索引
然后要读取时根据这个B-树来分段读取
理论上是这样
根据JAVA的特点,要做这个应该没问题的
因为XML都有一个开,一个关的标记,开的话就添加节点,关的话就回溯一层,顺序读一次就可以建立索引了