java 读取一个巨大的文本文件既能保证内存不溢出又能保证性能
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class ReadBig {
public static String fff = "C:\\mq\\read\\from.xml";
public static void main1(String[] args) throws Exception {
final int BUFFER_SIZE = 0x300000;// 缓冲区大小为3M
File f = new File(fff);
/**
*
* map(FileChannel.MapMode mode,long position, long size)
*
* mode - 根据是按只读、读取/写入或专用(写入时拷贝)来映射文件,分别为 FileChannel.MapMode 类中所定义的
* READ_ONLY、READ_WRITE 或 PRIVATE 之一
*
* position - 文件中的位置,映射区域从此位置开始;必须为非负数
*
* size - 要映射的区域大小;必须为非负数且不大于 Integer.MAX_VALUE
*
* 所以若想读取文件后半部分内容,如例子所写;若想读取文本后1/8内容,需要这样写map(FileChannel.MapMode.READ_ONLY,
* f.length()*7/8,f.length()/8)
*
* 想读取文件所有内容,需要这样写map(FileChannel.MapMode.READ_ONLY, 0,f.length())
*
*/
MappedByteBuffer inputBuffer = new RandomAccessFile(f, "r")
.getChannel().map(FileChannel.MapMode.READ_ONLY,
f.length() / 2, f.length() / 2);
byte[] dst = new byte[BUFFER_SIZE];// 每次读出3M的内容
long start = System.currentTimeMillis();
for (int offset = 0; offset < inputBuffer.capacity(); offset += BUFFER_SIZE) {
if (inputBuffer.capacity() - offset >= BUFFER_SIZE) {
for (int i = 0; i < BUFFER_SIZE; i++)
dst[i] = inputBuffer.get(offset + i);
} else {
for (int i = 0; i < inputBuffer.capacity() - offset; i++)
dst[i] = inputBuffer.get(offset + i);
}
int length = (inputBuffer.capacity() % BUFFER_SIZE == 0) ? BUFFER_SIZE
: inputBuffer.capacity() % BUFFER_SIZE;
System.out.println(new String(dst, 0, length));// new
// String(dst,0,length)这样可以取出缓存保存的字符串,可以对其进行操作
}
long end = System.currentTimeMillis();
System.out.println("读取文件文件一半内容花费:" + (end - start) + "毫秒");
}
public static void main2(String[] args) throws Exception {
int bufSize = 1024;
byte[] bs = new byte[bufSize];
ByteBuffer byteBuf = ByteBuffer.allocate(1024);
FileChannel channel = new RandomAccessFile(fff, "r").getChannel();
while (channel.read(byteBuf) != -1) {
int size = byteBuf.position();
byteBuf.rewind();
byteBuf.get(bs); // 把文件当字符串处理,直接打印做为一个例子。
System.out.print(new String(bs, 0, size));
byteBuf.clear();
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(fff));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
public static void main(String[] args) throws Exception {
int bufSize = 1024;
byte[] bs = new byte[bufSize];
ByteBuffer byteBuf = ByteBuffer.allocate(1024);
FileChannel channel = new RandomAccessFile("d:\\filename","r").getChannel();
while(channel.read(byteBuf) != -1) {
int size = byteBuf.position();
byteBuf.rewind();
byteBuf.get(bs);
// 把文件当字符串处理,直接打印做为一个例子。
System.out.print(new String(bs, 0, size));
byteBuf.clear();
}
}
}
java 读取大容量文件,内存溢出?怎么按几行读取,读取多次
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Scanner;
public class TestPrint {
public static void main(String[] args) throws IOException {
String path = "你要读的文件的路径";
RandomAccessFile br=new RandomAccessFile(path,"rw");//这里rw看你了。要是之都就只写r
String str = null, app = null;
int i=0;
while ((str = br.readLine()) != null) {
i++;
app=app+str;
if(i>=100){//假设读取100行
i=0;
// 这里你先对这100行操作,然后继续读
app=null;
}
}
br.close();
}
}
当逐行读写大于2G的文本文件时推荐使用以下代码
void largeFileIO(String inputFile, String outputFile) {
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(inputFile)));
BufferedReader in = new BufferedReader(new InputStreamReader(bis, "utf-8"), 10 * 1024 * 1024);//10M缓存
FileWriter fw = new FileWriter(outputFile);
while (in.ready()) {
String line = in.readLine();
fw.append(line + " ");
}
in.close();
fw.flush();
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
jdk本身就支持超大文件的读写。
网上的文章基本分为两大类,一类是使用BufferedReader类读写超大文件;另一类是使用RandomAccessFile类读取,经过比较,最后使用了前一种方式进行超大文件的读取,下面是相关代码,其实很简单
-------------------------------------------------------------------
File file = new File(filepath);
BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
BufferedReader reader = new BufferedReader(new InputStreamReader(fis,"utf-8"),5*1024*1024);// 用5M的缓冲读取文本文件
String line = "";
while((line = reader.readLine()) != null){
//TODO: write your business
}
---------------------------------------------------------------------
注意代码,在实例化BufferedReader时,增加一个分配缓存的参数即可
- Java中使用POI读取大的Excel文件或者输入流时发生out of memory异常参考解决方案
注意:此参考解决方案只是针对xlsx格式的excel文件! 背景 前一段时间遇到一种情况,服务器经常宕机,而且没有规律性,查看GC日志发生了out of memory,是堆溢出导致的,分析了一下堆的d ...
- java读取 500M 以上文件,java读取大文件
java 读取txt,java读取大文件 设置缓存大小BUFFER_SIZE ,Config.tempdatafile是文件地址 来源博客http://yijianfengvip.blog.163.c ...
- java 读取txt,java读取大文件
java 读取txt,java读取大文件 package com.bbcmart.util; import java.io.File;import java.io.RandomAccessFile;i ...
- Java读取Level-1行情dbf文件极致优化(2)
最近架构一个项目,实现行情的接入和分发,需要达到极致的低时延特性,这对于证券系统是非常重要的.接入的行情源是可以配置,既可以是Level-1,也可以是Level-2或其他第三方的源.虽然Level-1 ...
- Java读取Level-1行情dbf文件极致优化(3)
最近架构一个项目,实现行情的接入和分发,需要达到极致的低时延特性,这对于证券系统是非常重要的.接入的行情源是可以配置,既可以是Level-1,也可以是Level-2或其他第三方的源.虽然Level-1 ...
- java读取各类型的文件
java读取各类型的文件 用到的几个包 bcmail-jdk14-132.jar/bcprov-jdk14-132.jar/checkstyle-all-4.2.jar/FontBox-0.1.0-d ...
- Java读取并下载网络文件
CreateTime--2017年8月21日10:11:07 Author:Marydon import java.io.ByteArrayOutputStream; import java.io ...
- JAVA中获取文件MD5值的四种方法
JAVA中获取文件MD5值的四种方法其实都很类似,因为核心都是通过JAVA自带的MessageDigest类来实现.获取文件MD5值主要分为三个步骤,第一步获取文件的byte信息,第二步通过Messa ...
- linux中删除文件内空白行的几种方法。
linux中删除文件内空白行的几种方法 有时你可能需要在 Linux 中删除某个文件中的空行.如果是的,你可以使用下面方法中的其中一个.有很多方法可以做到,但我在这里只是列举一些简单的方法. 你可能已 ...
- PHP获取文件后缀名的三种方法
如下: <? PHP获取文件后缀名的几种方法1: function get_file_type($filename){ $type = substr($filename, strrpos($fi ...
随机推荐
- hdu-5721 Palace(最近点对)
题目链接: Palace Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- 西交校赛 F. GZP and Poker
F. GZP and Poker GZP often plays games with his friends.Today they went to a board game.There are n ...
- exception.py
try: raise Exception except Exception as e: print(e) try: raise Exception('comment') except Exceptio ...
- Cmake生成Makefile
cmake 相比automake 最大的区别是: 步骤没有automake那么多 main.cpp #include<iostream> #include"student.h&q ...
- 整合ssh的时候出现空指针java.lang.NullPointerException
转自:https://blog.csdn.net/koudailidexiaolong/article/details/9468857 HTTP Status 500 - type Exception ...
- Unity3D模型制作规范[转]
本文提到的所有数字模型制作,全部是用3D MAX建立的模型,即使是不同的驱动引擎,对模型的要求基本是相同的.当一个VR模型制作完成时,它所包含的基本内容包括:场景尺寸.单位,模型归类塌陷.命名.节点编 ...
- git cherry-pick简介(转载)
转自:http://hubingforever.blog.163.com/blog/static/1710405792012587115533/ 本文编辑整理自: http://sg552.iteye ...
- LeetCode.896-单调数组(Monotonic Array)
这是悦乐书的第345次更新,第369篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第210题(顺位题号是896).如果数组单调递增或单调递减,则数组是单调的.如果对于所有 ...
- git apply
1. git 安装 2.git 与服务器的验证 1.生成ssh ssh-keygen -t rsa -C "1107247128@qq.com" 2.查看生成的pub文件, ...
- servlet重定向到jsp后样式无法正常显示
原因是在servlet中转发时css和图片的路径变成相对于这个servlet的相对路径而非相对于web项目的路径了. 解决办法:导入css样式和图片时把css写成动态绝对路径, 如用EL表达式表示: ...