BufferedReader bf = new BufferedReader(reader);
定义一个缓冲数组。
然后开始处理。

解决方案 »

  1.   

    你出现 heap Overflow 并不是在于读的方式不对,而是在于读到一行一行的数据后,把这些数据都往一个集合里面塞了吧?如果是这样的话,无论有多大的内存都是无济于事的。正确的思路应该是一行一行地读取文件,每读取一行处理一行。
      

  2.   

    我把代码贴出来, 哪位高手能帮助修改一解决一下,万分感激.......
    程序是从zh.dat文本文件中一行一行读文本,如果有重复行做记录输出重复次数……
    待读文件zh.dat有近400M(约2000万行),运行程序报: “heap overflow”之后中断,当zh.dat大小在50M以下时,程序能正常运行。
    我知道是zh.dat文件400M太大所致,但我改了几次程序都无效,哪位高手能邦我一下?
    让程序能将400M的大文本一次处理完吗?
      

  3.   

    代码如下:
    import java.io.*;
    import java.util.*;
    import static java.util.Map.Entry;
    public class Sdup{
    public static void main(String[] args) {
        try{
            File file = new File("D:/search/zh.dat");
            FileWriter fw = new FileWriter("d:/search/dup.dat",true);
            PrintWriter pw = new PrintWriter(fw);
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(file)));
            String str = null;
            Map<String,Integer> map = new HashMap<String,Integer>();
            while((str = reader.readLine())!=null){
                map.put(str, map.get(str)==null?1:map.get(str)+1);
            }
            for(Entry<String, Integer> entry:map.entrySet()){
                if(entry.getValue() > 200){
                    System.out.println(entry.getKey()+"  Repeat Num:"+entry.getValue());
                    pw.println(entry.getKey()+"  Repeat Num:"+entry.getValue());
                    pw.flush();//Firsttime forgeted to use flush() dupzh.dat allways empty 
                } 
                else{
                 System.out.println("Not Found ");
                 }
             }
             pw.println("********Dupzh maked on "+new Date()+"************");
             pw.flush();
        }catch(IOException e){e.printStackTrace();}
        }
    }
      

  4.   

    果然是全部读取到内存中的
    这样肯定不行换个思路吧,先读取一行,然后一行一行遍历,重复就标记行数,比如用list
    接着换第二行.....
    以此类推这样可以记录下重复行的行数然后你就可以遍历一遍文件,去掉重复的,写入新文件
      

  5.   

    我第一个想到的是用MapReduce处理(好吧..最近在研究MR,第一反应就是用MR)
    帮LZ查了些资料http://sharong.iteye.com/blog/910989,File file = new File(filepath);     
    BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));      
    BufferedReader reader = new BufferedReader(new InputStreamReader(fis,"utf-8"),5*1024*1024);// 用5M的缓冲读取文本文件    
              
    String line = "";  
    while((line = reader.readLine()) != null){  
    //TODO: write your business  
    }  
    实例化BufferedReader时,增加一个分配缓存的参数即可
    楼主试试看吧
      

  6.   


    绝大多数的文本编辑器是一次性全部加载进内存的,只有少数的比如 EmEditor 可以批量加载。
      

  7.   


    绝大多数的文本编辑器是一次性全部加载进内存的,只有少数的比如 EmEditor 可以批量加载。
    VIM, Word...
      

  8.   

    11楼的方法 试了下 不行的 heap overflow
      

  9.   

    首先你要明白你的heap里面装的是什么。是ByteBuffer吗?你的heap是被那个map塞满的
      

  10.   

    用mapredurce 将内容分次处理
      

  11.   

    如果只是想处理该文件,而不是研究java怎么去读大文件的话,弄到linux上面用awk,分分钟搞定
      

  12.   


    Charset charset = Charset.defaultCharset();
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
    new FileOutputStream(FilePath, true), charset),1024*1024*20);
    另外,通过设置jvm运行参数-Xmx1350m,大小自己去调
      

  13.   

    最简单的快速的解决办法是调整内存堆的大小
    java -Xmx1g  ...
    如果1G不够,就2G或者更多。如果没有那么多内存可用,我们再说其他的解决办法:) 
      

  14.   

    大文本要边读边处理。Java对象比原始数据要大得多,400M文本读入内存中很可能会超过1G(如果读成字符串必然会超过,数值好一些),Java堆如果设置得不够就会溢出。有一个第三方工具润乾的集算器来处理大文本会快很多。集算器提供流式读入的功能,占用很少内存就可以对大文本做各种汇总、排序、分组,还可以用分段并行进一步提高性能,跟java程序集成简单,而且这个功能免费。
      

  15.   

    RandomAccessFile  这个应该能解决你的问题
      

  16.   

    赶紧回到正题上来程序是从zh.dat文本文件中一行一行读文本,如果有重复行做记录输出重复次数……
      

  17.   

    我先读取前1000行数据,存入map。map中比对这1000行数据,找出所有重复行。从1000行开始读取,到2000行……直到文件末尾。重复行如果少的话,就记录在内存中,如果多,就写入硬盘。
      

  18.   

    楼主换成我写的这个Map试试。虽然性能较低,应该不存在内存溢出的问题。
    import java.io.EOFException;
    import java.io.File;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.util.HashSet;
    import java.util.LinkedHashMap;public class HeavyMap extends LinkedHashMap<String, Integer> {
    private static final long serialVersionUID = -858815745597381386L;
    public static final int DEFAULT_CAPACITY = 2000;
    public static final String File_Prefix = "heavy_map";
    public static final String File_Suffix = "bin";
    private int capacity;// 内存对象容量
    private RandomAccessFile switchFile;// 数据交换文件
    private HashSet<Integer> virtualCache = new HashSet<Integer>(); public HeavyMap() throws IOException {
    this(DEFAULT_CAPACITY);
    } public HeavyMap(int capacity) throws IOException {
    this(capacity, File.createTempFile(File_Prefix, File_Suffix));
    } public HeavyMap(int capacity, File switchFile) throws IOException {
    super(16, 0.75f, true);
    this.capacity = capacity;
    if (switchFile.isDirectory()) {
    switchFile = File.createTempFile(File_Prefix, File_Suffix,
    switchFile);
    }
    this.switchFile = new RandomAccessFile(switchFile, "rw");
    } @Override
    public Integer put(String key, Integer value) {
    virtualCache.add(key.hashCode());
    return super.put(key, value);
    } @Override
    protected boolean removeEldestEntry(
    java.util.Map.Entry<String, Integer> eldest) {
    if (size() >= capacity) {
    updateEntry(eldest);
    return true;
    }
    return false;
    } @Override
    public Integer get(Object key) {
    Integer value = super.get(key);
    if (value == null && virtualCache.contains(key.hashCode())) {
    Integer v = findValue((String) key);
    if (v != null) {
    put((String) key, v);
    }
    }
    return value;
    } private Integer findValue(Object key) {
    synchronized (switchFile) {
    try {
    switchFile.seek(0L);
    long length = switchFile.length();
    while (switchFile.getFilePointer() < length) {
    int hash = switchFile.readInt();
    int len = switchFile.readInt();
    if (hash == key.hashCode()) {
    byte[] data = new byte[len - 4];
    if (switchFile.read(data) < 0) {
    throw new EOFException();
    }
    int valueNumber = switchFile.readInt();
    String keyString = new String(data, "UTF-8");
    if (keyString.equals(key)) {
    return valueNumber;
    }
    } else {
    switchFile.skipBytes(len);
    }
    }
    } catch (EOFException e) {
    return null;
    } catch (IOException e) {
    throw new IllegalStateException("读取交换区数据时产生异常", e);
    }
    }
    return null;
    } private void updateEntry(java.util.Map.Entry<String, Integer> e) {
    synchronized (switchFile) {
    try {
    switchFile.seek(0L);
    long length = switchFile.length();
    while (switchFile.getFilePointer() < length) {
    int hash = switchFile.readInt();
    int len = switchFile.readInt();
    if (hash == e.getKey().hashCode()) {
    byte[] data = new byte[len - 4];
    if (switchFile.read(data) < 0) {
    throw new EOFException();
    }
    int valueNumber = switchFile.readInt();
    String keyString = new String(data, "UTF-8");
    if (keyString.equals(e.getKey())
    && valueNumber != e.getValue()) {
    switchFile.seek(switchFile.getFilePointer() - 4);
    switchFile.writeInt(e.getValue());
    }
    } else {
    switchFile.skipBytes(len);
    }
    }
    } catch (IOException ex) {
    throw new IllegalStateException("读取交换区数据时产生异常", ex);
    }
    }
    } @Override
    protected void finalize() throws Throwable {
    super.finalize();
    switchFile.close();
    }
    }