300m的文件放进内存,那你的jvm分配的内存得够大

解决方案 »

  1.   

    string存不下,
    你看看这个吧!希望对你有帮助http://blog.csdn.net/mfx1986/article/details/5606228
      

  2.   

    当然可以你把JVM的内存扩大,前提是你有足够打的内存就可以加载。
      

  3.   

    OutOfMemoryError
    内存溢出- -
      

  4.   

    我想用lucene做对这些txt文档实现搜索并返回搜索内容,这必须要将txt文档保存到索引中,所以我要讲300M的txt文档读成string类型,但是这个不能实现,不知道要怎么实现。
      

  5.   

    1、这是可行的;前提是java的内存设置够大。String类型可以支持最大到2G的文件。
    2、这是没必要的;这样开销太大,建议重新设计。
      

  6.   

    楼主你说你要把文档内容转换到String里面再存储。这是不必要的。lucene的提供了 public Field(String name, Reader reader)这个方法,也就是说,你不用考虑将一个文件转换为string,只要传入Reader对象就可以了。然后再讲Field对象存放在Document里就ok了。
      

  7.   

    lucene提供的这个方法我也试过了,文件传入Reader对象,然后再讲Field对象存放在Document里,这里对文件内容是不存储的,如下:
    Field(String name, Reader reader) 
         Create a tokenized and indexed field that is not stored.
    不存储的话我最后搜索完之后就不能返回文档中我搜索的内容了。
    请问我要怎么实现呢?
      

  8.   

    额,楼主你用lucene来创建索引。最终是返回存储内容是吗?
    我想问下,你这个文件是什么样的?小说,还是想map中key和value对应的那种数据?你想返回关键字在哪一行还是其他?
      

  9.   

    嗯,是想返回存储文档的内容。我的数据如下所示:
    420 01143000024919 01143000025919 1.0
    420 01143000027126 01143000028142 1.0
    419 01143000034465 01143000035465 1.0
    418 01143000035872 01143000036872 1.0
    419 01143000036277 01143000037287 1.0
    416 01143000038867 01143000039867 1.0
    416 01143000040725 01143000041748 1.0
    ……………………
    ……………………
    很多很多,整个txt文档有300M左右,一共有五六个txt文档,我想实现的功能就是搜索时输入关键字,比如我输入420,它能返回给我
    420 01143000024919 01143000025919 1.0
    420 01143000027126 01143000028142 1.0
    就是将包含420的那一行数据都返回给我。
    这就是我为什么要对搜索的内容进行存储的原因,如果我不存储,就不能返回给我数据,可是五六个这么大的txt文档实在太大,就算实现存储感觉消耗也很大。是否有其他方法,比如返回我搜索的420在文档中的位置信息,然后我再通过这个位置信息直接打开文档查找等,不知这样是否可行?我现在刚开始学lucene,对它的研究还只是停留在很表面的层次,多谢您了~~
      

  10.   

    楼主我想了一下,上网搜了一下,发现其有还有很多方法可以实现的。比如public static void main(String[] args) throws Exception {
        int bufSize = 1024;
        byte[] bs = new byte[bufSize];
        // 这里是分配缓存大小。也就是用来存放从硬盘中度出来的文件
        // 什么叫一次把文件读出来?其实就是当缓存大小和在硬盘中文件大小一样,
        // 只通过一个read指令把整个文件都扔到缓存里面。例如要一次读一个2G的文件,把缓存设为2G就能一次读出来。
        // 不过当分配空间的时候,这个缓存根本是分配不出来的,因为内存不足。
        ByteBuffer byteBuf = ByteBuffer.allocate(bufSize);
        FileChannel channel = new RandomAccessFile("d:\\filename","r").getChannel();
        int size;
        // 因为这里缓存大小是1K,所以每个channel.read()指令最多只会读到文件的1K的内容。
        // 如果文件有1M大小,这里for会循环1024次,把文件分开1024次读取出来
        while((size = channel.read(byteBuf)) != -1) {
          byteBuf.rewind();
          byteBuf.get(bs);
          // 把文件当字符串处理,直接打印做为一个例子。
          System.out.print(new String(bs, 0, size));
          byteBuf.clear();
          //在这里可以执行lucene创索引的操作
        }
        channel.close();
      }
      

  11.   


    非常感谢您提供的这个办法,我照着试了一下,真的把我的所有数据都能读出来了,可是我在lucene建立索引的时候又遇到了一点新的问题,不知道您能不能再指导一下:
     while((size = channel.read(byteBuf)) != -1) {
          byteBuf.rewind();
          byteBuf.get(bs);
          // 把文件当字符串处理,直接打印做为一个例子。
          System.out.print(new String(bs, 0, size));
          byteBuf.clear();
          //在这里可以执行lucene创索引的操作
        }
    就是在上面这个while循环里添加lucene索引操作的话,就相当于对于我每次读出来的1k内容进行索引,那我每次循环建立的索引就会把前面的索引覆盖了,有什么办法可以不让出现覆盖而且把这些内容建立在一个索引中呢?
      

  12.   

    我大概试了一下,的确存在覆盖索引的问题。我这里的数据比较小
    我先声明一个全局String content
     while((size = channel.read(byteBuf)) != -1) {
          byteBuf.rewind();
          byteBuf.get(bs);
          // 把文件当字符串处理,直接打印做为一个例子。
          System.out.print(new String(bs, 0, size));
          byteBuf.clear();
          //在这里可以执行lucene创索引的操作
         // 我在这里content += new String(bs, 0, size)
        }
    最后我将content(就是整个内容)做一个创建索引。
    还是回到老问题了,其实。你的可能在读文件的时候,一下子放到内存里,导致内存不足。
    你再试试吧。
      

  13.   

    我试了一下。
    while((size = channel.read(byteBuf)) != -1) {
          byteBuf.rewind();
          byteBuf.get(bs);
          // 把文件当字符串处理,直接打印做为一个例子。
          System.out.print(new String(bs, 0, size));
          byteBuf.clear();
          //在这里可以执行lucene创索引的操作
         //这里每次new一个Document对象,然后add一个field都不会覆盖的啊。
        }
      

  14.   

    一开始我是把Document作为一个全局变量,然后也出现覆盖,放到while循环里就不会覆盖了,楼主试试。
      

  15.   

    这个问题其实最好的解决方式是,解析出来之后放到key-value内存数据库中