永发信息网

java 如何读取大文件

答案:4  悬赏:60  手机版
解决时间 2021-03-09 01:39
java 如何读取大文件
最佳答案
以下将从常规方法谈起,通过对比来说明应该如何使用java读取大文件。

1、常规:在内存中读取
读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法:
Files.readLines(new File(path), Charsets.UTF_8);
FileUtils.readLines(new File(path));
这种方法带来的问题是文件的所有行都被存放在内存中,当文件足够大时很快就会导致程序抛出OutOfMemoryError 异常。
例如:读取一个大约1G的文件:
@Test
public void givenUsingGuava_whenIteratingAFile_thenWorks() throws IOException {
String path = ...
Files.readLines(new File(path), Charsets.UTF_8);
}
这种方式开始时只占用很少的内存:(大约消耗了0Mb内存)
然而,当文件全部读到内存中后,我们最后可以看到(大约消耗了2GB内存):
这意味这一过程大约耗费了2.1GB的内存——原因很简单:现在文件的所有行都被存储在内存中。
把文件所有的内容都放在内存中很快会耗尽可用内存——不论实际可用内存有多大,这点是显而易见的。
此外,我们通常不需要把文件的所有行一次性地放入内存中——相反,我们只需要遍历文件的每一行,然后做相应的处理,处理完之后把它扔掉。所以,这正是我们将要做的——通过行迭代,而不是把所有行都放在内存中。

2、文件流
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);
}
// note that Scanner suppresses exceptions
if (sc.ioException() != null) {
throw sc.ioException();
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (sc != null) {
sc.close();
}
}
这种方案将会遍历文件中的所有行——允许对每一行进行处理,而不保持对它的引用。总之没有把它们存放在内存中:(大约消耗了150MB内存)

3、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);
}
由于整个文件不是全部存放在内存中,这也就导致相当保守的内存消耗:(大约消耗了150MB内存)
全部回答
java读取文件的方式有字节流和字符流!字符流
可以按行读取,控制好内存别溢出
可考虑bufferedinputstream和bufferedoutputstream来字节读取,这个代码太简单了,适用于非频繁操作。或采用nio的FileChannel,比较适合于高并发操作,如下为filechannel的部分代码
File inFile = new File("D:\\error");
File outFile = new File("D:\\to.txt");
FileChannel inFileChannel = new FileInputStream(inFile).getChannel();
FileChannel outFileChannel = new FileOutputStream(outFile).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while(-1 != inFileChannel.read(buffer)){
buffer.flip();
outFileChannel.write(buffer);
buffer.clear();
}
outFileChannel.close();
inFileChannel.close();
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
飞度前挡风玻璃周边塑料叫啥名字?
话说那个小野吉他社怎么样
苹果手机能用手机流量激活吗?
癌症患者能用带磁石的腰带吗
各个季节收获的农作物分别有哪些
中贸广场地址在什么地方,想过去办事
初三如何学好数理化备战中考
骑马与砍杀战团里的手里剑袋怎么获得,还有我
社区社会工作者将解决社区环境污染问题定为近
这种遥控器怎么装电池啊?
我新买的ZIPPO火机多打几次内胆就出来了,关
学习的定义说明( )。A.学习是行为或行为潜
博文便利店在什么地方啊,我要过去处理事情
关于高考的一些常识
车牌号816和916哪个好一些
推荐资讯
电脑编程题:计算1x2+2x3+3x4+4x5+···+100
书刊美术设计的特点之一是()。A.文化性与商
迷你世界怎么找地牢
有谁知道青岛哪有学习手语的地方?收费多少
杨咀地址在哪,我要去那里办事
李兰英卫生所在什么地方啊,我要过去处理事情
谁有关于看门狗CSI1161的编程资料?
日产逍客2012的发电机皮带怎么拆
梦见手上拔出来一根虫
武汉精诚新礼品公司在哪里啊,我有事要去这个
急 急 急 急 急 急 我要去江安,要做峨眉山到
请问谁知道使命召唤5游戏下载网站谢谢
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?