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 ); } }