java.lang.OutOfMemoryError:从URL下载大文件时的Java堆空间 [英] java.lang.OutOfMemoryError: Java heap space while downloading a large file from an URL

查看:386
本文介绍了java.lang.OutOfMemoryError:从URL下载大文件时的Java堆空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从URL下载文件.文件大小为564.31MB.我不知道这是怎么回事.另外,我想知道我的代码是否是从URL下载文件的正确方法.如果有更好的方法,请详细告诉我为什么它比这个更好.谢谢.

I want to download a file from an URL. The file size is 564.31MB. I have no clue what error is going on here. Also, I'm wondering if my code is the correct way to download a file from an URL. If there is a better way, please tell me in detail why it is better than this. Thanks.

import org.apache.commons.io.FilenameUtils;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by lukas on 6/30/16.
 */
public class Main {
    public static void main(String[] args){
        try {
            String link = "https://s.basketbuild.com/uploads/devs/dianlujitao/oneplus3/cm13/cm-13.0-20160621-UNOFFICIAL-oneplus3.zip";
            URL url = new URL(link);
            InputStream inputStream = new BufferedInputStream(url.openStream());
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int n=0;
            byte[] buf = new byte[1024];
            long duration = System.currentTimeMillis();
            while((n=inputStream.read(buf))!=-1){
                byteArrayOutputStream.write(buf, 0, n);
            }
            duration = System.currentTimeMillis()-duration;
            System.out.println("Finish in "+duration+"ms");

            inputStream.close();

            File dir = new File("Output path");
            if(!dir.exists())
                dir.mkdirs();

            String fileBaseName = FilenameUtils.getBaseName(link);
            String fileExtension = FilenameUtils.getExtension(link);
            System.out.println("Name: "+fileBaseName+'.'+fileExtension);
            File outputFile = new File(dir, fileBaseName+'.'+fileExtension);

            if(!outputFile.exists()){
                outputFile.createNewFile();
            }

            FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
            fileOutputStream.write(byteArrayOutputStream.toByteArray());

            //release outputstream
            byteArrayOutputStream.close();
            fileOutputStream.close();

            System.out.println("Your download has been finished");


        } catch (MalformedURLException e) {
            e.printStackTrace();
            System.out.println("Something unexpected has happened!");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Something unexpected has happened!");
        }


    }
}

这是我的控制台所说的:

Here is what my console says:

Finish in 133506ms
Name: cm-13.0-20160621-UNOFFICIAL-oneplus3.zip
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3236)
    at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:191)
    at Main.main(Main.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

推荐答案

  1. ByteArrayOutputStream在堆内存中分配其所有数据.正确的方法是直接写入文件,并为此使用缓冲区,以便优化磁盘I/O:

  1. ByteArrayOutputStream allocates all its data in the heap memory. The correct way is to write directly to the file, and use a buffer for that so disk I/O is optimized:

OutputStream os = new BufferedOutputStream(new FileOutputStream("myFile.txt"));

  • System.currentTimeMillis()为您提供当前日期和时间,该日期和时间可能随时更改.这并不是要计算持续时间,请使用SystemClock.nanoTime().

  • System.currentTimeMillis() gives you the current date and time, which may change at any point. It's not meant to calculate durations, use SystemClock.nanoTime() for that.

    这篇关于java.lang.OutOfMemoryError:从URL下载大文件时的Java堆空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆