RandomAccessFile raf = new RandomAccessFile(file, "r");            FileChannel channel = raf.getChannel();
            int size = (int) channel.size();
            MappedByteBuffer inbuff = channel.map(FileChannel.MapMode.READ_ONLY, 0,size);//当这里的size比较大的时候报java.lang.OutOfMemoryError: Map failed
/*
     下面就是拿到inbuff向文件里面写
*/
怎么实现文件的某一部分射到内存中,下一次再继续映射,麻烦给个例子

解决方案 »

  1.   

    既然是某一部分,那你为啥还要直接取size?
    取你需要的大小就是了
      

  2.   

    thinking in java 4th edition 
     I/O那一章里有关于nio的,我估计你看过了
      

  3.   

    seek
    public void seek(long pos)
              throws IOException设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。偏移量的设置可能会超出文件末尾。偏移量的设置超出文件末尾不会改变文件的长度。只有在偏移量的设置超出文件末尾的情况下对文件进行写入才会更改其长度。 参数:
    pos - 从文件开头以字节为单位测量的偏移量位置,在该位置设置文件指针。 
    抛出: 
    IOException - 如果 pos 小于 0 或者发生 I/O 错误。
      

  4.   

    我把代码附上,做过的帮个忙,谢谢了/*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package com.ny;import java.io.File;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.net.InetAddress;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;/**
     *
     * @author wangjing
     */
    public class FileTransferClient {    /**
         * 文件的读取用到两个类,第一个是RandomAccessFile用来支持断点续传,第二个是FileChannel是将文件映射到内存中来读取
         */
        public FileTransferClient() {/*
            InetAddress toIp;
            byte buf[];
            try {
            toIp = InetAddress.getByName("127.0.0.1");
            Socket client = new Socket(toIp, 6789);
            //1:得到写的流
            OutputStream os = client.getOutputStream();
            //2:制作输出流
            buf = "王靖".getBytes();
            //3:把输出流写出去,
            os.write(buf);
            os.flush();
            } catch (Exception ex) {
            ex.printStackTrace();
            }
             */    }    /**
         * 
         * @param file:这个方法是为了解决传入一个
         */
        public void accessFileTest(File file) {
            InetAddress toIp;
            RandomAccessFile raf = null;
            FileChannel channel = null;        FileChannel chx = null;
            RandomAccessFile put = null;
            
            MappedByteBuffer mabuff = null;
            try {
    //            toIp = InetAddress.getByName("127.0.0.1");
    //            Socket client = new Socket(toIp, 6789);
    //            ByteBuffer buff = ByteBuffer.allocate(8196);
    //            //1:得到写的流
    //            OutputStream os = client.getOutputStream();
    //            //2:制作输出流
                raf = new RandomAccessFile(file, "rw");            channel = raf.getChannel();
                int size = (int) channel.size();
                
                /*for(int i=0;i<size;i++){
                int c = buff.get;
                os.write(c);
                }*/            put = new RandomAccessFile(new File("f:\\test.rmvb"), "rw");
                chx = put.getChannel();
                //int s = (int)chx.size();
                //MappedByteBuffer putbuff = chx.map(FileChannel.MapMode.READ_WRITE, 0, size);            long l1 = System.currentTimeMillis();
                int position = 0;
                
                mabuff = channel.map(FileChannel.MapMode.READ_WRITE, 0,9612);//这里的size设置成其他的就报错,放成上面的size,在文件小于280M时都可以传,但是很大就不可以了,报错,大家可以试
                
                while (mabuff.hasRemaining()) //for(int i = 0;i<size;i++)
                {
                    //System.out.println(mabuff.get());
                   
                    chx.write(mabuff);
                    position = position + 9612;
                    //System.out.println(i);
                    //mabuff.clear();都试过了不好使
                    //mabuff.force();
                    mabuff = channel.map(FileChannel.MapMode.READ_WRITE, position, 9612);
                }
                long total = System.currentTimeMillis() - l1;
                System.out.println("所用时间" + total);
            //3:把输出流写出去,
            //os.write(buf);
            //os.flush();        } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                try {
                    channel.close();
                    raf.close();                chx.close();
                    put.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }    public static void main(String[] args) {
            FileTransferClient fc = new FileTransferClient();
            fc.accessFileTest(new File("e:\\media\\非常人贩2(中英字幕).rmvb"));
        }
    }像上面的代码来运行就报
    # java.lang.OutOfMemoryError: requested 64000 bytes for GrET in C:\BUILD_AREA\jdk6_06\hotspot\src\share\vm\utilities\growableArray.cpp. Out of swap space?
      

  5.   

    这是java1.4.2就有的一个bug,官方网站上有:
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5095540不过,sun似乎并没有解决这个问题,直接close并定义为不可重现:
    Bug ID:  5095540  
    Votes  30  
    Synopsis  JVM crash with outOfMemoryError in growableArray.cpp error  
    Category  hotspot:runtime_system  
    Reported Against  1.4.2_05  
    Release Fixed   
    State  11-Closed, Not Reproducible, bug  
    Priority:  2-High  
    Related Bugs   
    Submit Date  01-SEP-2004 
    --------------
    而java doc对map方法的说明也指出:For most operating systems, mapping a file into memory is more expensive than reading or writing a few tens of kilobytes of data via the usual read and write methods. From the standpoint of performance it is generally only worth mapping relatively large files into memory. 
    也就是说,对大部分操作系统而言,将文件映射到内存,比直接使用read方法读出几十KB要慢得多(expensive)。
      

  6.   

    我有测试了一下,这个SIZE设置的太小不行,效率太低,我直接设置10M,每个循环调用GC来回收内存,还是挺快的,
    而且也复制了1.7G的一个文件:
    size=1024*1024*10;//每次10M,不要太小,否则没有意义
                mabuff = channel.map(FileChannel.MapMode.READ_WRITE, 0,size);//这里的size设置成其他的就报错,放成上面的size,在文件小于280M时都可以传,但是很大就不可以了,报错,大家可以试
                
                while (mabuff.hasRemaining()) //for(int i = 0;i<size;i++)
                {
                    //System.out.println(mabuff.get());
                   
                    chx.write(mabuff);
                    position = position + size;
                    //System.out.println(i);
                    //mabuff.clear();都试过了不好使
                    //mabuff.force();
                    
                    mabuff = channel.map(FileChannel.MapMode.READ_WRITE, position, size);
                    System.gc();            }
      

  7.   


    是你原来自己的代码就有问题:我又改了一下:/**
         * 
         * @param file:这个方法是为了解决传入一个
         */
        public void accessFileTest(File file) {
            InetAddress toIp;
            RandomAccessFile raf = null;
            FileChannel channel = null;        FileChannel chx = null;
            RandomAccessFile put = null;
            
            MappedByteBuffer mabuff = null;
            try {
    //            toIp = InetAddress.getByName("127.0.0.1");
    //            Socket client = new Socket(toIp, 6789);
    //            ByteBuffer buff = ByteBuffer.allocate(8196);
    //            //1:得到写的流
    //            OutputStream os = client.getOutputStream();
    //            //2:制作输出流
                raf = new RandomAccessFile(file, "r");            channel = raf.getChannel();
                
                
                /*for(int i=0;i<size;i++){
                int c = buff.get;
                os.write(c);
                }*/            put = new RandomAccessFile(new File("f:\\test_new.rmvb"), "rw");
                chx = put.getChannel();
                //int s = (int)chx.size();
                //MappedByteBuffer putbuff = chx.map(FileChannel.MapMode.READ_WRITE, 0, size);            long l1 = System.currentTimeMillis();
                long position = 0;
                long size=1024*1024*50;//每次10M,不要太小,否则没有意义
                mabuff = channel.map(FileChannel.MapMode.READ_ONLY, 0,size);//这里的size设置成其他的就报错,放成上面的size,在文件小于280M时都可以传,但是很大就不可以了,报错,大家可以试
                long fileLen=raf.length();
                while (channel.position()<fileLen) //for(int i = 0;i<size;i++)
                {
                    //System.out.println(mabuff.get());
                   
                    chx.write(mabuff);
                    position = position+size;
                    //System.out.println(i);
                    //mabuff.clear();都试过了不好使
                    //mabuff.force();
                    if ((fileLen-position)<size){
                     size=fileLen-position;
                    }
                    if (size==0){
                     break;
                    }
                    System.out.println(raf.length()+":"+channel.position()+":"+size);
                    mabuff = channel.map(FileChannel.MapMode.READ_ONLY, position, size);
                    System.gc();
                }
                long total = System.currentTimeMillis() - l1;
                System.out.println("所用时间" + total);
                InputStream in=this.getClass().getResourceAsStream("");
            //3:把输出流写出去,
            //os.write(buf);
            //os.flush();        } catch (Exception ex) {
            
                ex.printStackTrace();
            } finally {
                try {
                    channel.close();
                    raf.close();                chx.close();
                    put.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }