完美解决java读取大文件内存溢出的问题

1. 传统方式:在内存中读取文件内容

读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法:

Files.readLines(new File(path), Charsets.UTF_8);
FileUtils.readLines(new File(path));

实际上是使用BufferedReader或者其子类LineNumberReader来读取的。

传统方式的问题: 是文件的所有行都被存放在内存中,当文件足够大时很快就会导致程序抛出OutOfMemoryError 异常。

问题思考:我们通常不需要把文件的所有行一次性地放入内存中,相反,我们只需要遍历文件的每一行,然后做相应的处理,处理完之后把它扔掉。所以我们可 以通过行迭代方式来读取,而不是把所有行都放在内存中。

2. 大文件读取处理方式

不重复读取与不耗尽内存的情况下处理大文件:

(1)文件流方式:使用java.util.Scanner类扫描文件的内容,一行一行连续地读取

FileInputStream inputStream = null;
Scanner sc = null;
try {
 inputStream = new FileInputStream(path);
 sc = new Scanner(inputStream, UTF-8);
 while (sc.hasNextLine()) {
  String line = sc.nextLine();
  // System.out.println(line);
  }
}catch(IOException e){
  logger.error(e);
}finally {
  if (inputStream != null) {
  inputStream.close();
  }
  if (sc != null) {
    sc.close();
   }
}

该方案将会遍历文件中的所有行,允许对每一行进行处理,而不保持对它的引用。总之没有把它们存放在内存中!

(2)Apache Commons IO流:使用Commons IO库实现,利用该库提供的自定义LineIterator

LineIterator it = FileUtils.lineIterator(theFile, UTF-8);
try {
 while (it.hasNext()) {
 String line = it.nextLine();
 // do something with line
  }
} finally {
 LineIterator.closeQuietly(it);
}

该方案由于整个文件不是全部存放在内存中,这也就导致相当保守的内存消耗。

以上这篇完美解决java读取大文件内存溢出的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 解析Java的JNI编程中的对象引用与内存泄漏问题

    JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互--在 Java 程序中调用 native code:在 native code 中嵌入 Java 虚拟机调用 Java 的代码. JNI 编程在软件开发中运用广泛,其优势可以归结为以下几点: 利用 native code 的平台相关性,在平台相关的编程中彰显优势. 对 native code 的代码重用. native code 底层操作

  • Java内存溢出和内存泄露

    虽然jvm可以通过GC自动回收无用的内存,但是代码不好的话仍然存在内存溢出的风险. 一.为什么要了解内存泄露和内存溢出? 1.内存泄露一般是代码设计存在缺陷导致的,通过了解内存泄露的场景,可以避免不必要的内存溢出和提高自己的代码编写水平: 2.通过了解内存溢出的几种常见情况,可以在出现内存溢出的时候快速的定位问题的位置,缩短解决故障的时间.  二.基本概念  理解这两个概念非常重要. 内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存.即被分配的对象可达但已无

  • 基于Java内存溢出的解决方法详解

    一.内存溢出类型1.java.lang.OutOfMemoryError: PermGen spaceJVM管理两种类型的内存,堆和非堆.堆是给开发人员用的上面说的就是,是在JVM启动时创建:非堆是留给JVM自己用的,用来存放类的信息的.它和堆不同,运行期内GC不会释放空间.如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改

  • java内存溢出示例(堆溢出、栈溢出)

    堆溢出: 复制代码 代码如下: /** * @author LXA * 堆溢出 */ public class Heap { public static void main(String[] args) { ArrayList list=new ArrayList(); while(true) { list.add(new Heap()); } } } 报错: java.lang.OutOfMemoryError: Java heap space 栈溢出: 复制代码 代码如下: /** * @a

  • Android性能优化之利用Rxlifecycle解决RxJava内存泄漏详解

    前言: 其实RxJava引起的内存泄漏是我无意中发现了,本来是想了解Retrofit与RxJava相结合中是如何通过适配器模式解决的,结果却发现了RxJava是会引起内存泄漏的,所有想着查找一下资料学习一下如何解决RxJava引起的内存泄漏,就查到了利用Rxlifecycle开源框架可以解决,今天周末就来学习一下如何使用Rxlifecycle. 引用泄漏的背景: RxJava作为一种响应式编程框架,是目前编程界网红,可谓是家喻户晓,其简洁的编码风格.易用易读的链式方法调用.强大的异步支持等使得R

  • JAVA程序内存溢出问题原因分析

    本文较为详细的分析了JAVA程序内存溢出问题原因.分享给大家供大家参考.具体如下: 遇到一个线上系统报 java.lang.OutOfMemoryError: PermGen space 错误,需要定位一下问题.很久之前到时弄过这个,现在还真有点不记得了,但这个真的是一个非常有意思的问题,值得好好研究一下.首先第一反应当然是加上-XX:+PrintGCDetails参数来看具体的GC日志,但是由于程序是tomcat启动的,担心里面封装的东西太多不好定位,既然在windows下面,所以还是借助可视

  • 编写Java代码制造一个内存溢出的情况

    这将会是一篇比较邪恶的文章,当你想在某个人的生活中制造悲剧时你可能会去google搜索它.在Java的世界里,内存溢出仅仅只是你在这种情况下可能会引入的一种bug.你的受害者会在办公室里度过几天甚至是几周的不眠之夜. 在这篇文章中我将会介绍两种溢出方式,它们都是比较容易理解和重现的.并且它们都是来源现实项目的案例研究,但是为了让你清晰地掌握,我把它们简化了. 不过放心,在我们遇到和解决了很过溢出bug之后,类似的案例将会比你想象得更加普遍. 先来一个进入状态的,在使用HashSet/HashMa

  • Java中关于内存泄漏出现的原因汇总及如何避免内存泄漏(超详细版)

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题.内存泄漏大家都不陌生了,简单粗俗的讲,就是该被释放的对象没有释放,一直被某个或某些实例所持有却不再被使用导致 GC 不能回收.最近自己阅读了大量相关的文档资料,打算做个 总结 沉淀下来跟大家一起分享和学习,也给自己一个警示,以后 coding 时怎么避免这些情况,提高应用的体验和质量. 我会从 java 内存泄漏的基础知识开始,并通过具体例子来说明 Android 引起内存泄漏的各种原因,以

  • 完美解决java读取大文件内存溢出的问题

    1. 传统方式:在内存中读取文件内容 读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法: Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path)); 实际上是使用BufferedReader或者其子类LineNumberReader来读取的. 传统方式的问题: 是文件的所有行都被存放在内存中,当文件足够大时很快就会

  • java读取大文件简单实例

    我要从一个文本文件中提有用的数据 文本文件200多MB 是不是可以建一个缓存来把有用的数据一段一段的提出来,请问该怎么做? --------------------------------------------------------------- 呵呵,200MB而已... JAVA中可以使用内存映射文件来操作大文件. 最大可达2GB. 下面是个简单的示例,更具体的自己看Java API DOCS或相关资料 复制代码 代码如下: import java.io.*; import java.n

  • 关于Poi读取Excel引发内存溢出问题的解决方法

    前言 最近生产环境有个老项目一直内存报警,不时的还出现内存泄漏,导致需要重启服务器,已经严重影响正常服务了. 分析 1.dump内存文件 liunx使用如下命令: ./jmap -dump:format=b,file=heap.hprof pid 2.使用Eclipse Memory Analysis进行分析 异常如下: at org.apache.poi.xssf.usermodel.XSSFRow.<init>(Lorg/openxmlformats/schemas/spreadsheet

  • Java高效读取大文件实例分析

    1.概述 本教程将演示如何用Java高效地读取大文件.Java--回归基础. 2.在内存中读取 读取文件行的标准方式是在内存中读取,Guava和ApacheCommonsIO都提供了如下所示快速读取文件行的方法: Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path)); 这种方法带来的问题是文件的所有行都被存放在内存中,当文件足够大时很快就会导致程序抛出OutOfMemoryErro

  • 完美解决keras 读取多个hdf5文件进行训练的问题

    用keras进行大数据训练,为了加快训练,需要提前制作训练集. 由于HDF5的特性,所有数据需要一次性读入到内存中,才能保存. 为此,我采用分批次分为2个以上HDF5进行存储. 1.先读取每个标签下的图片,并设置标签 def load_dataset(path_name,data_path): images = [] labels = [] train_images = [] valid_images = [] train_labels = [] valid_labels = [] counte

  • Java基础之堆内存溢出的解决

    一.实战-内存溢出 堆内存溢出 栈内存溢出 方法区溢出 直接内存溢出 二.实战-堆内存溢出 演示堆内存溢出代码,并且定位问题 总结堆内存溢出的场景与解决方案 分析商城项目中可能存在堆内存溢出的代码并且解决 三.堆内存溢出演示代码 public class HeapOOMTest { private List<String> oomList = new ArrayList<>(); public static void main(String[] args) { HeapOOMTes

  • Java实现按行读取大文件

    Java实现按行读取大文件 String file = "F:" + File.separator + "a.txt"; FileInputStream fis = new FileInputStream(file); RandomAccessFile raf = new RandomAccessFile(new File(file),"r"); String s ; while((s =raf.readLine())!=null){ Syste

  • 完美解决Java获取文件路径出现乱码的问题

    在Java中有时获取文件路径,获取的路径中存在中文或者是空格的时候,路径出现乱码.这个问题困扰了我好久,用过各种的转码都无济于事.在后来终于解决了,在这里和大家分享一下,其实也就是加一行代码的问题. 我在项目的是使用 String path = this.getClass().getClassLoader().getResource("/").getPath().substring(1); 这样来获得当前类的文件路径的.但是这样得到的是乱码.后来经过跟踪 在this.getClass(

  • 完美解决java.lang.OutOfMemoryError处理错误的问题

    原因: 常见的有以下几种: 1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据: 2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收: 3.代码中存在死循环或循环产生过多重复的对象实体: 4.使用的第三方软件中的BUG: 5.启动参数内存值设定的过小: 常见错误提示: 1.tomcat:java.lang.OutOfMemoryError: PermGen space 2.tomcat:java.lang.OutOfMemoryError: Java heap space 3

  • php 使用file_get_contents读取大文件的方法

    当我们遇到文本文件体积很大时,比如超过几十M甚至几百M几G的大文件,用记事本或者其它编辑器打开往往不能成功,因为他们都需要把文件内容全部放到内存里面,这时就会发生内存溢出而打开错误,遇到这种情况我们可以使用PHP的文件读取函数file_get_contents()进行分段读取. 函数说明 string file_get_contents ( string $filename [, bool $use_include_path [, resource $context [, int $offset

随机推荐