开发技术 / Technology
    您的当前位置:网站首页 > 行业洞察 > 开发技术

    java解决大数据读写问题

    日期:2015年5月25日  作者:zhjw  来源:互联网    点击:862

    把SRTM的数据读写了一下,可以用。

     

    JAVA内存映射文件:http://jiangzhengjun.iteye.com/blog/515745

     

    内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件。有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问。这种解决办法能大大简化修改文件的代码。
    fileChannel.map(FileChannel.MapMode mode, long position, long size)将此通道的文件区域直接映射到内存中。注意,你必须指明,它是从文件的哪个位置开始映射的,映射的范围又有多大;也就是说,它还可以映射一个大文件的某个小片断。


    MappedByteBuffer是ByteBuffer的子类,因此它具备了ByteBuffer的所有方法,但新添了force()将缓冲区的内容强制刷新到存储设备中去、load()将存储设备中的数据加载到内存中、isLoaded()位置内存中的数据是否与存储设置上同步。这里只简单地演示了一下put()和get()方法,除此之外,你还可以使用asCharBuffer( )之类的方法得到相应基本类型数据的缓冲视图后,可以方便的读写基本类型数据。

    Java代码 复制代码 收藏代码
    1. import java.io.RandomAccessFile;   
    2. import java.nio.MappedByteBuffer;   
    3. import java.nio.channels.FileChannel;   
    4.   
    5. public class LargeMappedFiles {   
    6.     static int length = 0x8000000// 128 Mb   
    7.   
    8.     public static void main(String[] args) throws Exception {   
    9.         // 为了以可读可写的方式打开文件,这里使用RandomAccessFile来创建文件。   
    10.         FileChannel fc = new RandomAccessFile("test.dat""rw").getChannel();   
    11.         //注意,文件通道的可读可写要建立在文件流本身可读写的基础之上   
    12.         MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);   
    13.         //写128M的内容   
    14.         for (int i = 0; i < length; i++) {   
    15.             out.put((byte'x');   
    16.         }   
    17.         System.out.println("Finished writing");   
    18.         //读取文件中间6个字节内容   
    19.         for (int i = length / 2; i < length / 2 + 6; i++) {   
    20.             System.out.print((char) out.get(i));   
    21.         }   
    22.         fc.close();   
    23.     }   
    24. }  
    [java] view plaincopy
     
    1. import java.io.RandomAccessFile;  
    2. import java.nio.MappedByteBuffer;  
    3. import java.nio.channels.FileChannel;  
    4.   
    5. public class LargeMappedFiles {  
    6.     static int length = 0x8000000// 128 Mb  
    7.   
    8.     public static void main(String[] args) throws Exception {  
    9.         // 为了以可读可写的方式打开文件,这里使用RandomAccessFile来创建文件。  
    10.         FileChannel fc = new RandomAccessFile("test.dat""rw").getChannel();  
    11.         //注意,文件通道的可读可写要建立在文件流本身可读写的基础之上  
    12.         MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);  
    13.         //写128M的内容  
    14.         for (int i = 0; i < length; i++) {  
    15.             out.put((byte'x');  
    16.         }  
    17.         System.out.println("Finished writing");  
    18.         //读取文件中间6个字节内容  
    19.         for (int i = length / 2; i < length / 2 + 6; i++) {  
    20.             System.out.print((char) out.get(i));  
    21.         }  
    22.         fc.close();  
    23.     }  
    24. }  

     

    尽管映射写似乎要用到FileOutputStream,但是映射文件中的所有输出 必须使用RandomAccessFile,但如果只需要读时可以使用FileInputStream,写映射文件时一定要使用随机访问文件,可能写时要读的原因吧。

     

    该程序创建了一个128Mb的文件,如果一次性读到内存可能导致内存溢出,但这里访问好像只是一瞬间的事,这是因为,真正调入内存的只是其中的一小部分,其余部分则被放在交换文件上。这样你就可以很方便地修改超大型的文件了(最大可以到2 GB)。注意,Java是调用操作系统的"文件映射机制"来提升性能的。

     

     

    package cn.edu.xjtu.nhpcc.jenva.file;
    import   java.io.*;   
    import   java.nio.*;   
    import   java.nio.channels.*;

    public class LargeFileReader {


       static   int   length   =   0x8FFFFFF;   //   128   Mb 
       
     /**
      * @param args
      * @throws IOException 
      * @throws FileNotFoundException 
      */
     public static void main(String[] args) throws FileNotFoundException, IOException {
     
      /* The following works well.
         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   
        */
      
      /* The following is ours. */
      FileChannel fc = new RandomAccessFile( "srtm1","r").getChannel();
      System.out.println(fc.size());
      long maxValue = length;
      if (maxValue>fc.size()) {
       maxValue = fc.size();
      }
      
         MappedByteBuffer out =  fc.map(FileChannel.MapMode.READ_ONLY, 0, maxValue);   
         
         FileWriter fw = new FileWriter("srtm1-2");
         int line =3601;
         
         
         for(int   i   =   0;   i   <   maxValue;   i++) {
          if (i != 0 &&i %(maxValue/line) == 0 ) {
           
           fw.append("/n");
           fw.append((char)out.get(i));
          }else {
           if (i<maxValue){
            //System.out.print((char)out.get(i));
            fw.append((char)out.get(i));
           }
          }
         } 
         fw.close();
    }
    }

     

     

     

    package cn.edu.xjtu.nhpcc.jenva.file;

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;

    public class FileReaderTest {

     /**
      * @param args
      * @throws IOException 
      */
     public static void main(String[] args) throws IOException {
      // TODO Auto-generated method stub

      /*
      MyFileReader f = new MyFileReader();
      f.reader("hi");
      */
      
      /*
       * 下面这段代码,读出来的长度连空格也算。
       */
      /*
      BufferedReader is = new BufferedReader(new FileReader("dbPoolParameter"));
      ArrayList<Float> a = new ArrayList<Float>();
       
       String s = is.readLine();
       System.out.println(s.length());
       */
      
      /*
       * 下面这段代码,读出来的是纯数字,空格不计入。
       */
       /*
      BufferedReader is = new BufferedReader(new FileReader("srtm1"));
      ArrayList<Float> a = new ArrayList<Float>();
      
       String s = is.readLine();
       s.trim();
       String b[] = s.split(" ");
       System.out.println(b.length);
      
       for (int i=0; i<b.length; i++) {
       System.out.println(b[i]); 
       }
       //System.out.println(s);
        */
      
      
      /*
       * 下面这段代码,处理大文件的读写。
       */
      BufferedReader is = new BufferedReader(new FileReader("srtm1-2"));
      ArrayList<Float> a = new ArrayList<Float>();
      int line = 2;
      for (int i=0; i<line; i++) {
       String s = is.readLine();
        s.trim();
        String b[] = s.split(" ");
        System.out.println(b.length);
       
        for (int j=0; j<b.length; j++) {
        System.out.println(b[j]); 
        }
        System.out.println("********************************");
      }
     }

    }