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 引入的文件内存映射方案,读写性能很高。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)