Java nio(文件读写 实例解析)

来源:互联网 发布:mac rar暴力破解 编辑:程序博客网 时间:2024/05/16 02:44

读写操作是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,容量和最大容量都为1024ByteBuffer

    ByteBuffer bb = ByteBuffer.allocate(1024);

    //fcbuffer中读入数据

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) fcinbuffer读数据之前,使用clear();

2) bufferfcout写数据之前,使用flip;

 

-----------------------------------------------------------------

    buffer.clear();

    intr = fcin.read(buffer);

   

    if(r==1){

       break;

}

 

buffer.flip();

fcout.write(buffer);

    -----------------------------------------------------------------

 

    CopyFile.java全文:

    -----------------------------------------------------------------

    static public void main( Stringargs[] ) throws Exception {

        if (args.length<2) {

         System.err.println( "Usage: java CopyFile infile outfile" );

         System.exit( 1 );

        }

        Filefile = new File("");

        String infile = args[0];

        String outfile = args[1];

 

        FileInputStreamfin = new FileInputStream( infile );

    FileOutputStream fout = new FileOutputStream(outfile );

 

        FileChannelfcin = fin.getChannel();

    FileChannel fcout =fout.getChannel();

 

        ByteBufferbuffer = ByteBuffer.allocate( 1024 );

 

        while (true) {

            buffer.clear();

 

        int r = fcin.read( buffer );

 

        if (r==-1) {

           break;

            }

       buffer.flip();

       fcout.write( buffer ); }

     }

    -----------------------------------------------------------------