jubincn

导航

JavaIO学习

参考:

Java IO:  http://www.ibm.com/developerworks/cn/java/j-lo-javaio/

Java NIO: http://www.ibm.com/developerworks/cn/education/java/j-nio/

这里写的东西为自己的总结,学习的话建议大家仔细去读上面提到的两篇文章。

Java IO分为两种:Blocking IO(BIO) & Non blocking IO(NIO)

BIO

Java中BIO包括基于字节的Stream,基于字符的Writer&Reader等,在使用时优先使用Reader&Writer。BIO经常用于与Property类一起使用读取properties文件,如下所示:

public class StreamProps {	
	
	public void testStream() throws IOException{
		Properties props = new Properties();
		String path = Thread.currentThread().getContextClassLoader().getResource("").getPath().substring(1);
		File testFile = new File(path + "test.txt");
		
		FileReader rd = new FileReader(testFile);
		props.load(rd);

		FileWriter wt = new FileWriter(testFile);
		props.store(wt, "Write finished");		
		wt.close();
	}
	
	public static void main(String[] args) throws IOException{
		Stream stream = new Stream();
		stream.testStream();
	}
}

NIO

NIO的好处从名字可以看出来,可以节省资源,尤其是对于服务器,这种方式是几乎是必需的。与BIO基于流的方式不同,NIO是基于块的IO,这样对提升读取效率。NIO中这几个部分是基础:Channel,Buffer和Server端常用的Selector。

Channel:双向,用于数据传输。

Buffer:用于缓存数据

Selector:根据监听的端口来寻找注册的Channel

下面这段代码用于实现文件拷贝,使用了Channel和Buffer:

public class  NIO {	
	
	private FileInputStream fin;
	private FileOutputStream fout;

	public void copyFile() throws IOException{
		String path = Thread.currentThread().getContextClassLoader().getResource("").getPath().substring(1);
		File beforeFile = new File(path + "before.txt");
		fin = new FileInputStream(beforeFile);
		File afterFile = new File(path + "after.txt");	
		fout = new FileOutputStream(afterFile);
		FileChannel fcin = fin.getChannel();
		FileChannel fcout = fout.getChannel();
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		
		while(true){
			buffer.clear();
			
			if( fcin.read(buffer) == -1 ) break;
			buffer.flip();
			fcout.write(buffer);
		}
	}
	
	public static void main(String[] args) throws IOException{
		NIO nio = new NIO();
		nio.copyFile();
	}
}
下面这个例子介绍了Server端NIO的使用,源码来自:http://www.ibm.com/developerworks/cn/education/java/j-nio/

import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;

public class MultiPortEcho
{
  private int ports[];
  private ByteBuffer echoBuffer = ByteBuffer.allocate( 1024 );

  public MultiPortEcho( int ports[] ) throws IOException {
    this.ports = ports;

    go();
  }

  private void go() throws IOException {
    // Create a new selector
    Selector selector = Selector.open();

    // Open a listener on each port, and register each one
    // with the selector
    for (int i=0; i<ports.length; ++i) {
      ServerSocketChannel ssc = ServerSocketChannel.open();
      ssc.configureBlocking( false );
      ServerSocket ss = ssc.socket();
      InetSocketAddress address = new InetSocketAddress( ports[i] );
      ss.bind( address );

      SelectionKey key = ssc.register( selector, SelectionKey.OP_ACCEPT );

      System.out.println( "Going to listen on "+ports[i] );
    }

    while (true) {
      int num = selector.select();

      Set selectedKeys = selector.selectedKeys();
      Iterator it = selectedKeys.iterator();

      while (it.hasNext()) {
        SelectionKey key = (SelectionKey)it.next();

        if ((key.readyOps() & SelectionKey.OP_ACCEPT)
          == SelectionKey.OP_ACCEPT) {
          // Accept the new connection
          ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
          SocketChannel sc = ssc.accept();
          sc.configureBlocking( false );

          // Add the new connection to the selector
          SelectionKey newKey = sc.register( selector, SelectionKey.OP_READ );
          it.remove();

          System.out.println( "Got connection from "+sc );
        } else if ((key.readyOps() & SelectionKey.OP_READ)
          == SelectionKey.OP_READ) {
          // Read the data
          SocketChannel sc = (SocketChannel)key.channel();

          // Echo data
          int bytesEchoed = 0;
          while (true) {
            echoBuffer.clear();

            int r = sc.read( echoBuffer );

            if (r<=0) {
              break;
            }

            echoBuffer.flip();

            sc.write( echoBuffer );
            bytesEchoed += r;
          }

          System.out.println( "Echoed "+bytesEchoed+" from "+sc );

          it.remove();
        }

      }

//System.out.println( "going to clear" );
//      selectedKeys.clear();
//System.out.println( "cleared" );
    }
  }

  static public void main( String args[] ) throws Exception {
    if (args.length<=0) {
      System.err.println( "Usage: java MultiPortEcho port [port port ...]" );
      System.exit( 1 );
    }

    int ports[] = new int[args.length];

    for (int i=0; i<args.length; ++i) {
      ports[i] = Integer.parseInt( args[i] );
    }

    new MultiPortEcho( ports );
  }
}



posted on 2013-04-26 09:33  jubincn  阅读(273)  评论(0编辑  收藏  举报