这是我编写一段文件分割器代码,当我写入小的文件时,可以分割的,但是大的文件放进去,就内存溢出,求指教
package com.chenyan;import java.io.*;
public class FenGe {
private String path;
private String shuchu;
private int n;

public FenGe(String path,String shuchu,int n){
this.path=path;
this.shuchu=shuchu;
this.n=n;
}

public  void fun() throws IOException{
File file =new File(path);
long s=file.length();
System.out.println(s);
byte[] bytes=toByteArray(file);//文件的字节数
int count=bytes.length/n;//被分后每个文件的大小
String name=file.getName();//得到文件名称
String[] strs=name.split("\\.");
for(int i=0;i<n;i++){
String mingzi=strs[0]+"_"+i;
String houzhui = strs[1];
mingzi=mingzi.concat(".");
name=mingzi.concat(houzhui);
int begin=i*count;
if(i==n-1){
count=bytes.length-i*count;
}
write(shuchu+"\\"+name,bytes,begin,count);
}
} private  void write(String path, byte[] bytes, int begin, int count) throws IOException {
OutputStream out=new FileOutputStream(path);
out.write(bytes,begin,count);
out.close();
} private static byte[] toByteArray(File file) throws IOException {
InputStream in=new BufferedInputStream(new FileInputStream(file));
ByteArrayOutputStream out=new ByteArrayOutputStream();
byte[] buff=new byte[1024];
int cnt;
byte[] bytes=new byte[(int)file.length()];
while((cnt=in.read(buff))!=-1){
out.write(buff,0,cnt);
}
    bytes=out.toByteArray();
in.close();
out.close();
return bytes;
}
}
这是报错Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at com.chenyan.FenGe.toByteArray(FenGe.java:51)
at com.chenyan.FenGe.fun(FenGe.java:21)
at com.chenyan.MyFrame$5.actionPerformed(MyFrame.java:290)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6134)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5899)
at java.awt.Container.processEvent(Container.java:2023)
at java.awt.Component.dispatchEventImpl(Component.java:4501)
at java.awt.Container.dispatchEventImpl(Container.java:2081)
at java.awt.Component.dispatchEvent(Component.java:4331)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4301)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3965)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3895)
at java.awt.Container.dispatchEventImpl(Container.java:2067)
at java.awt.Window.dispatchEventImpl(Window.java:2458)
at java.awt.Component.dispatchEvent(Component.java:4331)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

解决方案 »

  1.   

    面向文件的开发应该尽量全过程采用流式操作的思想,楼主你把所有切割后的文件全放在内存里是不合适的。应该直接创建目标文件,然后边读边写,程序里面只需要维护一个不太大的buffer,比如4K或8K。
      

  2.   

    嗯没看你代码但一次太多就用buffer读一点处理一点
      

  3.   

    偽代碼就差不多這樣InputStream is = inputStreamInstance;
    FileOutputSream fos = fileOutputStreamInstance;buffer = is.readOneBuffer();while(buffer != null) {
        fos.write(buffer);
        buffer = is.readOneBuffer();
    }
      

  4.   

    打错了,is.readOneBuffer();是什么意思
      

  5.   

    楼主的这句话有问题:byte[] bytes=new byte[(int)file.length()];
    不能这样。只需要读一部分就行了。FileInputStream input = new FileInputStream("D:/workspace/CSDNTest/src/com/test/Test.java");
    byte[] b = new byte[1024];//可以设置得更大,会更快速读取数据
    int len = 0;
    while ((len = input.read(b)) != -1) {
    System.out.print(new String(b,0,len));//这里可以使用输出流输出到文件中。
    }
      

  6.   

    楼主设计的代码,本身就不能分割大数据文件。
    如果,我没理解错的话。楼主是想,先将待分割的文件数据读入到内存当中,
    然后按文件的实际大小平均分成n个小文件。第一步,将源文件完完全全读入到内存中,就不适合大文件的分割。
    因为,电脑的内存是有限的,JVM使用的内存也是有限的。楼主看看我的想法如何。
    1.通过文件名称,创建文件对象,获得文件大小。
    2.通过文件大小和参数n,可以得到每个小文件的大小。
    3.编写一个子函数,将源文件的InputStream写入到小文件中,写满为止。
    4.编写一个循环,调用步骤3中的子函数,生成多个小文件。
    其中,步骤3的子函数中,创建byte[] buff=new byte[1024];作为缓冲区,其他位置不用缓冲区。
      

  7.   

    用缓冲,buffredInputStream,buffredOutputStream
      

  8.   

    有时候缓存也解决不了问题,况且这个不是缓不缓存的问题,而是全读进内存的问题。
    因为一般JAVA JRE规定不能超过500M,当然对于这个阈值你可以自己在JAVA中设置,比如你的电脑是工作站的话,内存达到16G,就可以多设点。一般JAVA heap space报错是当占用内存达到当前电脑可用内存的80%时出现。但是根本解决方案是改变你的算法,即编程思路。下面链接会有详细介绍,利用递归的手法分配调入内存,处理一部分数据释放一部分资源。
    http://blog.csdn.net/gaowen_han/article/details/7171893
    里面运用到了对5000个文件180M数据同时使用split以及读写。
      

  9.   

    你能告诉我你的文件有多大嘛/?超过1G嘛如果没有,就是你程序问题!
    如果超过了,就使用FileRandonAccess来读写
      

  10.   

    byte[] b = new byte[1024];一次读一小段嘛
      

  11.   


    这位说的很清楚了。 楼主要读的文件不是大文件(大于4G的),只是栈中能分配的空间有限(我测试了下 最大分配170M),所以修改这里:byte[] bytes=new byte[1024]; 就可以了。
      

  12.   

    可以只读一部分或者是把JVM调大点~