java channel 读写文件_FileChannel按行读取文件

程序员面试金典(第6版)[美]盖尔·

120.6元

(需用券)

去购买 >

ff967f43868725064a478a7868624be3.png

FileChannel是什么

它是用于读取、写入、映射和操作文件的通道。除了熟悉的字节通道读取,写入和关闭操作之外,此类还定义了以下特定于文件的操作:

可以以不影响通道当前位置的方式在文件中的绝对位置读取或写入字节。

文件的区域可以直接映射到内存中。 对于大文件,这通常比调用通常的读取或写入方法要有效得多。

对文件所做的更新可能会被强制发送到基础存储设备,以确保在系统崩溃时不会丢失数据。

字节可以从文件传输到其他通道,反之亦然,可以通过许多操作系统进行优化,将字节快速传输到文件系统缓存或直接从文件系统缓存传输。

文件的区域可能被锁定,以防止其他程序访问。

FileChannel配合着ByteBuffer,将读写的数据缓存到内存中,然后以批量/缓存的方式read/write,省去了非批量操作时的重复中间操作,操纵大文件时可以显著提高效率。ByteBuffer可以使用直接内存(系统内存)(allocateDirect),使用后无需jvm回收。

总结一下,按照字节读取,对大文件读取效率更高,无法设置为非阻塞模式,它总是运行在阻塞模式下。

但有时候我们要按照行读取文件,而FileChannel只能按照字节读取,所以这里需要对换行进行判断一下,在这里我对其进行了实现,供大家参考。

实现

import java.io.*;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

public class test1 {

public static void readLineByChannel(String path) throws IOException {

long lineNumber = 0;

FileInputStream fileIn = new FileInputStream(path);

FileChannel fileChannel = fileIn.getChannel();

// 开始按行读取

int bufferSize = 1024 * 1024; // 每一块的大小

ByteBuffer buffer = ByteBuffer.allocate(bufferSize);

byte b;

while(fileChannel.read(buffer) > 0)

{

buffer.flip();

for (int i = 0; i < buffer.limit(); i++)

{

b = buffer.get();

if(b==10){ // 如果遇到换行

lineNumber++;

}

}

buffer.clear(); // 清空buffer

}

fileChannel.close();

System.out.println(lineNumber);

}

public static void readLineByBufferedReader(String path) throws IOException {

long lineNumber = 0;

FileInputStream inputStream = new FileInputStream(path);

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

String line;

while((line=bufferedReader.readLine()) != null)

{

lineNumber++;

}

inputStream.close();

bufferedReader.close();

System.out.println(lineNumber);

}

public static void main(String[] args) throws IOException {

String path = "大文件";

long startTime = System.currentTimeMillis();

readLineByChannel(path);

System.out.println("readLineByChannel耗时:" + (System.currentTimeMillis() - startTime));

startTime = System.currentTimeMillis();

readLineByBufferedReader(path);

System.out.println("readLineByBufferedReader耗时:" + (System.currentTimeMillis() - startTime));

}

}

使用FileChannel和BufferedReader分别的对大文件进行读取,并且计算有多少行。

//第一次测试:

169860474

readLineByChannel耗时:27310

169860474

readLineByBufferedReader耗时:24944

//第二次测试

169860474

readLineByChannel耗时:28677

169860474

readLineByBufferedReader耗时:21229

测试文件12GB,可以看出文件有1亿6千多万行,实际测试下来两者差距不大,甚至BufferedReader还快点。

java 11官方入门(第8版)教材

79.84元

包邮

(需用券)

去购买 >

f0f3f55624fb396b1764d42d6df88864.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值