介绍一下Java NIO,NIO读取文件都有哪些方法

介绍一下Java NIO,NIO读取文件都有哪些方法,第1张

NIO也就是New I/O,是一组扩展Java IO *** 作的API集, 于Java 1.4起被引入,Java 7中NIO又提供了一些新的文件系统API,叫NIO2.

NIO2提供两种主要的文件读取方法

使用buffer和channel类

使胡举吵用Path 和 File 类

NIO读取文件有以下三种方式:

1. 旧的NIO方式,使用BufferedReader

import java.io.BufferedReader

import java.io.FileReader

import java.io.IOException

public class WithoutNIOExample

{

public static void main(String[] args)

{

BufferedReader br = null

String sCurrentLine = null

try

{

br = new BufferedReader(

new FileReader("test.txt"))

while ((sCurrentLine = br.readLine()) != null)

{

System.out.println(sCurrentLine)

}

}

catch (IOException e)

{

e.printStackTrace()

}

finally

{

try

{

if (br != null)

br.close()

} catch (IOException ex)

{

ex.printStackTrace()

}

}

}

}

2. 使用buffer读取小文件

import java.io.IOException

import java.io.RandomAccessFile

import java.nio.ByteBuffer

import java.nio.channels.FileChannel

public class ReadFileWithFileSizeBuffer

{

public static void main(String args[])

{

try

{

RandomAccessFile aFile = new RandomAccessFile(

"test.txt","r")

FileChannel inChannel = aFile.getChannel()

long fileSize = inChannel.size()

ByteBuffer buffer = ByteBuffer.allocate((int) fileSize)

inChannel.read(buffer)

buffer.rewind()

buffer.flip()

for (int i = 0i <fileSizei++)

{

System.out.print((char) buffer.get())

}

inChannel.close()

aFile.close()

}

catch (IOException exc)

{

System.out.println(exc)

System.exit(1)

}

}

}

3. 分块答伍读取大文件

import java.io.IOException

import java.io.RandomAccessFile

import java.nio.ByteBuffer

import java.nio.channels.FileChannel

public class ReadFileWithFixedSizeBuffer

{

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

{

RandomAccessFile aFile = new RandomAccessFile

("test.txt", "r")

FileChannel inChannel = aFile.getChannel()

ByteBuffer buffer = ByteBuffer.allocate(1024)

while(inChannel.read(buffer) >0)

{

buffer.flip()

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

{

System.out.print((char) buffer.get())

}

buffer.clear()// do something with the data and clear/compact it.

}

inChannel.close()

aFile.close()

}

}

4. 使用MappedByteBuffer读取文件

import java.io.RandomAccessFile

import java.nio.MappedByteBuffer

import java.nio.channels.FileChannel

public class ReadFileWithMappedByteBuffer

{

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

{

RandomAccessFile aFile = new RandomAccessFile

("test.txt", "r")

FileChannel inChannel = aFile.getChannel()

MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size())

buffer.load()?

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

{

System.out.print((char) buffer.get())

}

buffer.clear()// do something with the data and clear/compact it.

inChannel.close()

aFile.close()

}

}

尽管Java提供了 java.io.File 这样一个 *** 作文件的类,但并没有提供一个复制文件的方法。

然而,当我们需要对磁盘上的文件进行处理的时候,这是一个很重要的方法。在这个时候我们往往不得不自己实现这样一个完成文件复制 *** 作的方法。下面将会介绍4种常见的文件复制的实现,并比较下它们的性能。

能找到的最常见经典例子。从文件A的输入流读取一批字节,写到文件B的输出流。

如你所见,这种实现方式需要多次读取数据,再写入将数据写入,因此受限于我们提供的buffer的大小,他的效率有点一般。

Java NIO类库里引入了一个叫 transferFrom 的方法,文档里说这是一个会比 FileStream 方式更快的复制 *** 作。

Appache Commons IO 提供了一旅镇个 FileUtils.copyFile(File from, File to) 方法用于文件复制,如果项目里使用到了这个类库,使用这个方法是个不错的选择。它的内部也是使用Java NIO的 FileChannel 实现的。

如果对Java 7 的使用有经验的话,那应该接触过 Files 这个工具类。

由于项目里没用到 Apache Common IO ,Android仅支持 Java 7 的语法特性,因此我只测试了前两种,数据如下:

复制文件,大小2M

复制文件,大小4.5M

复制文件,大小8M

复制文件,大小161M

从数据上可以看出,使用 FileStream 的方式,复制的效率跟我们的buffer大小取值关系很大,这无疑加大了我们使用它进行文件复制的负担。

而NIO的方式则不然模镇孙,无论是小文件、还是大文件,它的效率旦链都跟我们测试 FileStream 的最好水平相当!

因此,把 FileStream 这种老旧的实现方式从项目里挪走吧,是时候用上 FileChannel 了。

2016年06月16日 14:04 更新

大致就是从输入里映射一部分作为buffer,写到输出去,Buffer的大小最大为8388608,如果剩余的文件长度小于这个值,则用剩余文件长度的大小为buffer大小,继续写入,直到完全写完。

需要注意到的是,buffer并不是我们平时使用的byte数组,而是 MappedByteBuffer 对象,这是 java nio 引入的文件内存映射方案,读写性能很高。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12286829.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存