介绍一下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()

}

}

io,也称old io,读取文件主要通过流,从磁盘上一个一个字符的读,效率比较低下。

nio,在对文件 *** 作下改进了方式,通过块读取,一整块一整块的读取,所以读取出来的不会是一个字符,而是一个块,把这些数据放到内存缓冲区内。在进行 *** 作。通过块的读取来提高速度。(块 *** 作,fileChannel)

内存映射,MappedByteBuffer,这个主要是通过内存映射,即利用虚拟内存(把文件某一部分当成内存),直接 *** 作文件,对于一些要在内存中大块 *** 作的文件,比如1G的文件

你要在内存中 *** 作200M的部分,,把200M读到物理内存是比较耗内存和CPU的,不如直接把那部分文件虚拟成内存直接 *** 作。

下面是对用以上三个文式对一个300M的文件进行读取,并写入另一个文件的测试:

1. inputstream CPU5.6% 内存2.6M costTime:4.039S 使用缓冲区byte:4kb

2. filechannelCPU1.3% 内存2.6M costTime:3.359S 使用缓冲区byte:0(transferTo方式)

3. MappedByteBufferCPU6.9% 内存2.4M costTime:6.966S 内存映射:300M

可见对大文件块读取是最好的如果要直接 *** 作文件的很大的一部分的内容,则比较适合MappedByteBuffer 如读取很小的内容,比如8B的内容,inputStream可能是最好的。

代码如下,选几个文件自已试下。使用jdk自带JConsole进行观察。

public class Test {

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

File ff=new File("F:/workspace/pureMQ/src/mq/pure/file/cc.rar")

File[] f=new File[7]

File[] f_write=new File[7]

Thread.sleep(15000)

for(int i=0i<7i++){

f[i]=new File("F:/workspace/pureMQ/src/mq/pure/file/1"+(i+1)+".jpg")

}

for(int i=0i<7i++){

f_write[i]=new File("F:/workspace/pureMQ/src/mq/pure/file/"+i+".jpg")

if(!f_write[i].exists()){

f_write[i].createNewFile()

}

}

f[0]=ff

long begin=System.currentTimeMillis()

int choice=1

for(int i=0i<7i++){

switch(choice){

case 1:

System.out.println("1")

InputStream ips=new FileInputStream(f[i])

OutputStream ops=new FileOutputStream(f_write[i])

byte[] b=new byte[4096]

int index

while((index=ips.read(b))!=-1){

ops.write(b)

}

if(ips!=null){

ips.close()

}

if(ops!=null){

ops.close()

}

break

case 2:

System.out.println("2")

RandomAccessFile raf=new RandomAccessFile(f[i],"r")

RandomAccessFile raf_write=new RandomAccessFile(f_write[i],"rw")

FileChannel fc=raf.getChannel()

FileChannel fc_write=raf_write.getChannel()

fc.transferTo(0, fc.size(), fc_write)

fc.close()

fc_write.close()

raf.close()

raf_write.close()

break

case 3:

System.out.println("3")

RandomAccessFile raf2=new RandomAccessFile(f[i],"r")

RandomAccessFile raf2_write=new RandomAccessFile(f_write[i],"rwd")

FileChannel fc2=raf2.getChannel()

FileChannel fc2_write=raf2_write.getChannel()

MappedByteBuffer mbb=fc2_write.map(MapMode.READ_WRITE, 0, fc2.size())

ByteBuffer bb=ByteBuffer.allocate(4096)

while(fc2.read(bb)!=-1){

bb.flip()

mbb.put(bb)

bb.compact()

}

mbb.force()

fc2.close()

fc2_write.close()

raf2.close()

raf2_write.close()

break

default:

break

}

}

long end=System.currentTimeMillis()

System.out.println("all time cost:"+ (end-begin))

}

}


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存