在处理1G ~ 10G 的xml文件时,发现挺慢。请问有什么可以优化的?代码上有什么注意的? 运行时有什么可以提高性能的设置码?

解决方案 »

  1.   

    这个使用java.nio,并采用分段读取的方法是可以解决的。你自己上网查查吧
    MappedByteBuffer inputBuffer =
                 new FileInputStream(file).getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileLength);//读取大文件
      

  2.   

    读1G到10G xml文件,够大的,进来学习。
    以前没弄过。
      

  3.   

    10G的xml? 里面是什么信息这么大? 你自己做的数据库?
      

  4.   

    这么大的文件肯定不能一次都读入内存~~~~~~~~
    JAVA中可以使用内存映射文件来操作大文件.   
    最大可达2GB.   
    下面是个简单的示例,更具体的自己看Java   API   DOCS或相关资料   
    import   java.io.*;   
    import   java.nio.*;   
    import   java.nio.channels.*;   
    public   class   LargeMappedFiles   {   
        static   int   length   =   0x8FFFFFF;   //   128   Mb   
        public   static   void   main(String[]   args)   throws   Exception   {   
            MappedByteBuffer   out   =     
                new   RandomAccessFile( "test.dat ",   "rw ").getChannel()   
                .map(FileChannel.MapMode.READ_WRITE,   0,   length);   
            for(int   i   =   0;   i   <   length;   i++)   
                out.put((byte) 'x ');   
            System.out.println( "Finished   writing ");   
            for(int   i   =   length/2;   i   <   length/2   +   6;   i++)   
                System.out.print((char)out.get(i));       //read   file   
        }   
    }   ///   
      

  5.   

    要对这10G的xml文件做什么样的操作?
      

  6.   

    谢谢楼上各位的回答,目前用的是org.xml.sax.XMLReader 在做xml解析, 目前只试过512m大小的文件。org.xml.sax.XMLReader 对于使用它自己还有什么可以优化的吗?xml是某东西的log,所以会很大。
      

  7.   

    你用的SAX实现是什么?JDK默认的?
    apache的xerces比JDK的实现快至少30倍
      

  8.   

    一点一点的吧?
    我好像在说废话有一个东西叫google
    最大可达2GB. import  java.io.*; 
    import  java.nio.*; 
    import  java.nio.channels.*; 
    public  class  LargeMappedFiles  { 
        static  int  length  =  0x8FFFFFF;  //  128  Mb 
        public  static  void  main(String[]  args)  throws  Exception  { 
            MappedByteBuffer  out  =   
                new  RandomAccessFile( "test.dat ",  "rw ").getChannel() 
                .map(FileChannel.MapMode.READ_WRITE,  0,  length); 
            for(int  i  =  0;  i  <  length;  i++) 
                out.put((byte) 'x '); 
            System.out.println( "Finished  writing "); 
            for(int  i  =  length/2;  i  <  length/2  +  6;  i++) 
                System.out.print((char)out.get(i));      //read  file 
        } 
    } 我也不知道对不对
      

  9.   

    我试了下,xerces和标准jdk的。 
    貌似读100M的文件的时间几乎一样。
    难道jdk就是用xerces?
      

  10.   


    XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");XMLReaderFactory.createXMLReader();
    上面2种都试了下,貌似速度上没有什么区别,几乎完全一样。
    (当然第2种的时候,我把xercesImpl.jar删除了,应该是用了jdk标准的了吧?)
    是不是我写的有问题?
      

  11.   

    读取xml  恩   帮你顶了
      

  12.   

    http://download.csdn.net/source/353401
    NIO 入门 - IBM 教程.chm使用nio提高io速度
      

  13.   

    读一点处理一点绝对不行.因为xml有起始标记.读一点的时候可能把一个标记分开到两次处理.自己重写readLine方法,不以\r\n为结尾,以xml的结束标记为结尾.这样每读一行以正则表达式来处理绝对比所有的XML解析器要快上百倍.
      

  14.   

    你是要对这个XML做什么动作?
    如果只是解析,那么建议你采用32楼的办法,自己写专用的解析器,比通用的要快多了
      

  15.   

    学习
    同意LS 和LSS的做法!
      

  16.   

    分段?人家是要解析,不是拷贝,xml是严格要求起始标记的。楼主可以考虑下32楼的方法。
      

  17.   

    log?谁设计的,log都写到一个文件里啊?
    不按照大小分割啊。
      

  18.   

    从整个方案而言这肯定是下三流的方案。一天的log有1-10G那你不能按小时来写log吗?而且每小时的log先预处理一下。而本贴的主题不是如何产生log,有可能这个log就是客户给你的,如何产生你控制不了。现在就是一个1-10G的文件,要想处理。每一行log肯定有开始和结束标记。比如<log>any</log>
    现在要重 写readLine,就是读到</log>说明读完了一行。然后对这一行进行分解。这是最快的方案,其它任何xml解释器在读10G文件时都是死路一条。
      

  19.   

    读取3G的文件都没问题  
      private static void test1() throws IOException {
            System.out.println("start..");
            long start = System.currentTimeMillis();
            int buffersize = 1024 * 1024;
            OutputStream outputStream = new FileOutputStream(new File("f:/test1.rar"));
            InputStream isInputStream = new FileInputStream(new File("d:\\hahaha.rar"));
            byte[] buffer = new byte[buffersize];
            int readCount = 0;
            while ((readCount = isInputStream.read(buffer, 0, buffersize)) > 0) {
                // System.out.println(readCount);
                outputStream.write(buffer, 0, readCount);        }
            outputStream.close();
            isInputStream.close();
            System.out.println("end.." + (System.currentTimeMillis() - start) / 1000.0 + "s");    }