Java Nio 實現檔案的傳輸
阿新 • • 發佈:2019-02-13
使用Java Nio實現檔案的傳輸
1、ServerSocket.java
ClientSocket.javapackage ch2; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.FileChannel.MapMode; import java.nio.channels.FileChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class ServerSocket { public static void main(String[] args) throws Exception { int port = 10000; //開啟伺服器套接字通道 ServerSocketChannel ssc = ServerSocketChannel.open(); //建立一個選擇器 Selector selector = Selector.open(); //設定非阻塞模式 ssc.configureBlocking(false); InetSocketAddress address = new InetSocketAddress(port); //繫結監聽埠 ssc.bind(address); //註冊選擇器,保持等待模式 ssc.register(selector, SelectionKey.OP_ACCEPT); System.out.println("伺服器已開啟,埠:"+port); while(true){ selector.select(); //返回此選擇器的已選擇鍵集 Set<SelectionKey> keys=selector.selectedKeys(); Iterator<SelectionKey> iterKey=keys.iterator(); while(iterKey.hasNext()){ SelectionKey sk=iterKey.next(); //測試此鍵的通道是否已準備好接受新的套接字連線 if(sk.isAcceptable()){ SocketChannel sc=ssc.accept(); try { //接收 new ReceiveAndSend().receiveFile(sc); sc.close(); } catch (Exception e) { } } } } } }
package ch2; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.SocketChannel; public class ClientSocket { public static void main(String[] args) throws Exception { int port=10000; String ip = "localhost"; //開啟傳輸通道 SocketChannel sc = SocketChannel.open(); //連線 sc.connect(new InetSocketAddress(ip,port)); //傳送檔案 new ReceiveAndSend().sendFile(sc, "e:"+File.separator+"node.txt","node.txt"); //關閉傳輸通道 sc.close(); } }
ReceiveAndSend.java
package ch2; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; public class ReceiveAndSend { /** * 接收檔案 * @param sc * @throws IOException */ public void receiveFile(SocketChannel sc) throws IOException{ //獲取儲存檔案 File file=new File("e:"+File.separator+"mmm.txt"); FileOutputStream fos=new FileOutputStream(file); //獲取通道 FileChannel foc = fos.getChannel(); //設定接收訊息體緩衝區 ByteBuffer bb=ByteBuffer.allocateDirect(1024); //設定接收訊息頭緩衝區 ByteBuffer headByte=ByteBuffer.allocateDirect(32); //接收訊息頭 sc.read(headByte); byte[] b=new byte[32]; headByte.flip(); for (int i = 0; headByte.hasRemaining(); i++) { b[i]=headByte.get(); } headByte.clear(); //獲取檔案資訊 String fileInfo=new String(b,Charset.forName("UTF-8")); String[] strInfo=fileInfo.split("\\|"); System.out.println("檔案:"+strInfo[0]+"--大小:"+strInfo[1]); int read=sc.read(bb); while(read!=-1){ bb.flip(); //寫入到輸出通道 foc.write(bb); bb.clear(); read=sc.read(bb); } foc.close(); fos.close(); } /** * 傳送檔案 * @param sc * @param path * @param fileName * @throws IOException */ public void sendFile(SocketChannel sc,String path,String fileName) throws IOException{ File file=new File(path); FileInputStream fis = new FileInputStream(file); FileChannel fic = fis.getChannel(); ByteBuffer bb = ByteBuffer.allocateDirect(1024); ByteBuffer headbb = ByteBuffer.allocateDirect(32); int read=0; long fileSize = file.length(); long sendSize=0; System.out.println("檔案大小:"+fileSize); //拼接頭資訊 String head=fileName+"|"+fileSize+"|;"; //將頭資訊寫入緩衝區 headbb.put(head.getBytes(Charset.forName("UTF-8"))); int c=headbb.capacity()-headbb.position(); //填滿頭資訊 for (int i = 0; i < c; i++) { headbb.put(";".getBytes(Charset.forName("UTF-8"))); } headbb.flip(); //將頭資訊寫入到通道 sc.write(headbb); do{ //將檔案寫入到緩衝區 read = fic.read(bb); sendSize+=read; bb.flip(); //將檔案寫入到通道 sc.write(bb); bb.clear(); System.out.println("已傳輸/總大小:"+sendSize+"/"+fileSize); }while(read!=-1&&sendSize<fileSize); System.out.println("檔案傳輸成功"); fic.close(); fis.close(); } }