Java nio(文件读写 实例解析)
读写操作是I/O操作的基本行为;NIO中从Channel中读数据非常简单:创建一个buffer;通过一个channel完成buffer的数据读入;写数据同样简单:创建一个buffer;向其中填充数据;然后通过一个channel完成buffer的数据写入;
下面通过java的实际例子进行说明:
NIO读操作:
原来的IO中需要先创建一个FileInputStream然后完成读操作;
NIO读数据时因为数据最终都驻留在buffer中,所以你只需要从channel中读取数据到buffer对象中;
NIO中读取数据的步骤:1)从FileInputStream中得到Channel对象;2)创建一个buffer对象;3)从Channel中读数据到Buffer中;
javaCode:
-------------------------------------------------------------------------------------------------------------------------
//从FileInputStream中获取channel对象
FileInputStream fis = new FileInputStream(new File("D://1.txt"));
FileChannel fc = fis.getChannel();
//生成一个偏移量为0,容量和最大容量都为1024的ByteBuffer
ByteBuffer bb = ByteBuffer.allocate(1024);
//fc向buffer中读入数据
fc.read(bb);
--------------------------------------------------------------------------------------------------------------------------
你可能会注意到这里我们并不需要要求channel对象读入多少buffer数据,每个buffer对象内部有一个复杂的计数系统来跟踪已经读取的数据和剩余可读的buffer数据空间;
NIO写数据:
javacode:
--------------------------------------------------------------------------------------------------------------------------
//从FileOutputStream中获取一个文件流;
FileOutputStream fos = new FileOutputStream("D:/1.txt");
FileChannel fc = fos.getChannel();
//创建一个buffer并把准备写的数据填充进去;
ByteBuffer bb = ByteBuffer.allocate(1024);
//数据源
byte[] message = {1,2,42,'a',3};
bb.put(message);
bb.flip();
//一定得有,如果没有,就是从文件最后开始读取的。通过这个语句,就能把buffer的当前位置更改为buffer缓冲区的第一个位置。这样就可以从buffer开头,对该buffer进行遍历(读取)了。
//实际的写操作;
fc.write(bb); -----------------------------------------------------------------
这里同样的,我们不需要告诉Channel对象我们将要写入多少个字节,buffer内部有自己的计数系统来跟踪记录已经包含的数据和还可以写入数据的空间;
NIO的同时读操作和写操作:
举一个CopyFile的例子:从一个文件中复制数据到另一个文件中;其中包含三个基本操作:
创建一个Buffer,然后从从一个源文件中读取数据到buffer中,继而把buffer中的数据写入到目标文件中; Read->Write->Read->Write;该过程一直重复直至完成复制;
所以核心的循环代码如下:
-----------------------------------------------------------------
fcin.read(buffer);//read
fout.write(buffer);//write
-----------------------------------------------------------------
控制的循环终点: int r = fcin.read(buffer);
if(r==-1) 可以作为循环控制的终点;
重新定位Buffer位置:
1)
在fcin向buffer读数据之前,使用clear();
2)
在buffer向fcout写数据之前,使用flip;
-----------------------------------------------------------------
buffer.clear();
int r = fcin.read(buffer);
if(r==1){
break;
}
buffer.flip();
fcout.write(buffer);
-----------------------------------------------------------------
CopyFile.java全文:
-----------------------------------------------------------------
static public void main( String args[] ) throws Exception {
if (args.length<2) {
System.err.println( "Usage: java CopyFile infile outfile" );
System.exit( 1 );
}
File file = new File("");
String infile = args[0];
String outfile = args[1];
FileInputStream fin = new FileInputStream( infile );
FileOutputStream fout = new FileOutputStream( outfile );
FileChannel fcin = fin.getChannel();
FileChannel fcout = fout.getChannel();
ByteBuffer buffer = ByteBuffer.allocate( 1024 );
while (true) {
buffer.clear();
int r = fcin.read( buffer );
if (r==-1) {
break;
}
buffer.flip();
fcout.write( buffer ); }
}
-----------------------------------------------------------------