Java读写大文本文件(2GB以上)
如下的程序,将一个行数为fileLines的文本文件平均分为splitNum个小文本文件,其中换行符'r'是linux上的,windows的java换行符是'\r\n':
package kddcup2012.task2.FileSystem; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader; public class FileSplit
{
public static void main(String[] args) throws IOException
{
long timer = System.currentTimeMillis();
int bufferSize = 20 * 1024 * 1024;//设读取文件的缓存为20MB //建立缓冲文本输入流
File file = new File("/media/Data/毕业设计/kdd cup/数据/userid_profile.txt");
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
InputStreamReader inputStreamReader = new InputStreamReader(bufferedInputStream);
BufferedReader input = new BufferedReader(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);
}
}
以上程序处理大文本文件只需要30MB左右的内存空间(这和所设的读取缓冲大小有关),但是速度不是很快,在磁盘没有其他程序占用的情况下,将200MB文件分割为112份需要20秒(机器配置:Centrino2 P7450 CPU,2GB DDR3内存,Ubuntu 11.10系统,硬盘最大读写速度大约60MB/S)。
另外,对于几百兆到2GB大小的文件,使用内存映射文件的话,速度会块一些,但是内存映射由于映射的文件长度不能超过java中int类型的最大值,所以只能处理2GB以下的文件。
package helloword.helloword; 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); 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 main3(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();
}
} }
package helloword.helloword; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
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();
}
}
}
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
}
Java读写大文本文件(2GB以上)的更多相关文章
- java读写大文件
java读写2G以上的大文件(推荐使用以下方法) static String sourceFilePath = "H:\\DataSource-ready\\question.json&qu ...
- java读取大文本文件
原文:http://blog.csdn.net/k21325/article/details/53886160 小文件当然可以直接读取所有,然后放到内存中,但是当文件很大的时候,这个方法就行不通了,内 ...
- java filechannel大文件的读写
java读取大文件 超大文件的几种方法 转自:http://wgslucky.blog.163.com/blog/static/97562532201332324639689/ java 读取一个 ...
- Java读写文本文件操作
package com.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; ...
- java处理大文本2G以上
面试中经常碰到类似问题,问题的关键我觉得是用设置一个缓冲区 还有一个思路 是通过Linux split 命令将文件直接切割成小文件,再进行处理再汇总. 或者jdk7提供的 forkjoin 框架,利用 ...
- Java查询大文本
但JAVA本身缺少相应的类库,需要硬编码才能实现结构化文件计算,代码复杂且可读性差,难以实现高效的并行处理. 使用免费的集算器可以弥补这一不足.集算器封装了丰富的结构化文件读写和游标计算函数,书写简单 ...
- java读写文件大全
java读写文件大全 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类,这两个类都是抽象类,Writer中 write(char[] ch,int o ...
- java读写
IO流下分为字节流与字符流,每个流又分为输入输出以及读写. 字节流的两个基类为InputStream与OutputStream. 字符流为Reader和Writer
- 【Java】大文本字符串滤重的简单方案~
本文章也同步至本人的CSDN博客中: http://blog.csdn.net/u012881584/article/details/70477832 今天来说一个Java中处理大文本字符串虑重的两个 ...
随机推荐
- iOS 开发--Objective-C 反射机制
了解反射机制 Objective-C语言中的OC对象,都继承自NSObject类.这个类为我们提供了一些基础的方法和协议,我们可以直接调用从这个类继承过来方法.当然,本篇文章中讲到的反射方法,就在NS ...
- 扩展 delphi 泛型 以实现类似lambda功能 , C#中的any count first last 等扩展方法
扩展 delphi 泛型 以实现类似lambda功能 , C#中的any count first last 等扩展方法 在C#中对泛型的扩展,输入参数是泛型本身的内容,返回值则是bool.基于这一点, ...
- 快笑死,侯捷研究MFC的原因
与我研究VCL框架代码的原因一模一样:就是N年了,感觉自己还是没有掌握Delphi,惊叹别人各种各样神奇的效果,自己却不会,更不知为什么这样做,离高手的距离还有十万八千里.而且编程的时候,就像侯捷说的 ...
- Linux配置自建 YUM 软件存储库
yum软件仓库的搭建方式有三种,分别是本地yum源,网络yum源,第三方软件仓库. 以下示例演示了搭建本地yum仓库的方法: 1. 删除 /etc/yum.repos.d/dvd.repo 这个仓库文 ...
- ado执行sql查询出现“发送数据流时出现算术溢出”错误
开发一个数据采集监控系统,比较变态的是有将近2000项数据.根据数据类型分多个表存储.数据库访问层采用ado.最近发现当一条sql一次性查询1700多个字段数据后就出现“发送数据流时出现算术溢出”错误 ...
- Eclipse 下如何引用另一个项目的资源文件
为什么要这么做?可参考:Eclipse 下如何引用另一个项目的Java文件 下面直接说下步骤:(项目A 引用 项目B的资源文件) 1.右键 项目A,点击菜单 Properties 2.在弹出的框中,点 ...
- php去除数组中重复数据
<?php /** * 去除数组中重复数据 * by www.jbxue.com **/ $input = array("a" => "green" ...
- VS2015中添加新建项,找不到ado .net entity datamodel的解决方法
http://stackoverflow.com/questions/23046081/missing-ado-net-entity-data-model-on-visual-studio-2013 ...
- Android:将View的内容映射成Bitmap转图片导出
前段时间在网上看到这么个例子是将view映射到一个bitmap中,稍加改进可以用于一些截图工具或者截图软件(QQ截图之类),例子写的不够完善,不过很有些学习的意义内容大致如下: 在Android中自有 ...
- NHibernate 二级缓冲
session.CreateCriteria(typeof(SysModuleFields)).SetCacheable(true).List<SysModuleFields>(); se ...