java 超大文本_java处理大文本2G以上

本文介绍了在Java中处理大文本文件的几种方法,包括使用缓冲区、Linux split命令、JDK7的ForkJoin框架,以及内存映射文件。提供了一个程序示例,演示如何将大文本文件平均分割成小文件,该程序使用20MB的缓冲区,并展示了读取大文件的不同策略,以避免内存溢出并保持性能。
摘要由CSDN通过智能技术生成

面试中经常碰到类似问题,问题的关键我觉得是用设置一个缓冲区

还有一个思路 是通过Linux split 命令将文件直接切割成小文件,再进行处理再汇总。

或者jdk7提供的 forkjoin 框架,利用forkjoinpool管理的线程池,处理此种问题,未尝试过。

以下内容转自: http://blog.csdn.net/sysmedia/article/details/78030113

如下的程序,将一个行数为fileLines的文本文件平均分为splitNum个小文本文件,其中换行符'r'是linux上的,windows的java换行符是'\r\n':

48304ba5e6f9fe08f3fa1abda7d326ab.png

packagekddcup2012.task2.FileSystem;

importjava.io.BufferedInputStream;

importjava.io.BufferedReader;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileWriter;

importjava.io.IOException;

importjava.io.InputStreamReader;

public classFileSplit

{

public static void main(String[] args) throwsIOException

{

long timer =System.currentTimeMillis();

int bufferSize = 20 * 1024 * 1024;//设读取文件的缓存为20MB

//建立缓冲文本输入流

File file = new File("/media/Data/毕业设计/kdd cup/数据/userid_profile.txt");

FileInputStream fileInputStream = newFileInputStream(file);

BufferedInputStream bufferedInputStream = newBufferedInputStream(fileInputStream);

InputStreamReader inputStreamReader = newInputStreamReader(bufferedInputStream);

BufferedReader input = newBufferedReader(inputStreamReader, bufferSize);

int splitNum = 112-1;//要分割的块数减一

int fileLines = 23669283;//输入文件的行数

long perSplitLines = fileLines / splitNum;//每个块的行数

for (int i = 0; i <= splitNum; ++i)

{

//分割

//每个块建立一个输出

FileWriter output = new FileWriter("/home/haoqiong/part" + i + ".txt");

String line = null;

//逐行读取,逐行输出

for (long lineCounter = 0; lineCounter < perSplitLines && (line = input.readLine()) != null; ++lineCounter)

{

output.append(line + "\r");

}

output.flush();

output.close();

output = null;

}

input.close();

timer = System.currentTimeMillis() -timer;

System.out.println("处理时间:" +timer);

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

以上程序处理大文本文件只需要30MB左右的内存空间(这和所设的读取缓冲大小有关),但是速度不是很快,在磁盘没有其他程序占用的情况下,将200MB文件分割为112份需要20秒(机器配置:Centrino2 P7450 CPU,2GB DDR3内存,Ubuntu 11.10系统,硬盘最大读写速度大约60MB/S)。

另外,对于几百兆到2GB大小的文件,使用内存映射文件的话,速度会块一些,但是内存映射由于映射的文件长度不能超过java中int类型的最大值,所以只能处理2GB以下的文件。

java 读取一个巨大的文本文件既能保证内存不溢出又能保证性能

48304ba5e6f9fe08f3fa1abda7d326ab.png

packagehelloword.helloword;

importjava.io.BufferedReader;

importjava.io.File;

importjava.io.FileReader;

importjava.io.RandomAccessFile;

importjava.nio.ByteBuffer;

importjava.nio.MappedByteBuffer;

importjava.nio.channels.FileChannel;

public classReadBig {

public static String fff = "C:\\mq\\read\\from.xml";

public static void main1(String[] args) throwsException {

final int BUFFER_SIZE = 0x300000;//缓冲区大小为3M

File f = newFile(fff);

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) throwsException {

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 main3(String[] args) throwsException {

BufferedReader br = new BufferedReader(newFileReader(fff));

String line = null;

while ((line = br.readLine()) != null) {

System.out.println(line);

}

}

public static void main(String[] args) throwsException {

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();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

java 读取大容量文件,内存溢出?怎么按几行读取,读取多次。最佳答案

48304ba5e6f9fe08f3fa1abda7d326ab.png

packagehelloword.helloword;

importjava.io.BufferedInputStream;

importjava.io.BufferedReader;

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileNotFoundException;

importjava.io.FileReader;

importjava.io.FileWriter;

importjava.io.IOException;

importjava.io.InputStreamReader;

importjava.io.RandomAccessFile;

importjava.util.Scanner;

public classTestPrint {

public static void main(String[] args) throwsIOException {

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的文本文件时推荐使用以下代码

voidlargeFileIO(String inputFile, String outputFile) {

try{

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(newFile(inputFile)));

BufferedReader in = new BufferedReader(new InputStreamReader(bis, "utf-8"), 10 * 1024 * 1024);//10M缓存

FileWriter fw = newFileWriter(outputFile);

while(in.ready()) {

String line =in.readLine();

fw.append(line + " ");

}

in.close();

fw.flush();

fw.close();

} catch(IOException ex) {

ex.printStackTrace();

}

}

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

jdk本身就支持超大文件的读写。

网上的文章基本分为两大类:

一类是使用BufferedReader类读写超大文件;

另一类是使用RandomAccessFile类读取,经过比较,最后使用了前一种方式进行超大文件的读取,下面是相关代码,其实很简单

-------------------------------------------------------------------

48304ba5e6f9fe08f3fa1abda7d326ab.png

File file = newFile(filepath);

BufferedInputStream fis = new BufferedInputStream(newFileInputStream(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

}

48304ba5e6f9fe08f3fa1abda7d326ab.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值