IO |
單向傳輸 |
NIO |
異步雙向傳輸 |
1 //使用非直接緩衝區 傳輸數據 2 //經過流的方式 3 @Test 4 public void NoDirect(){ 5 6 FileInputStream fileInputStream = null; 7 FileOutputStream fileOutputStream =null; 8 FileChannel fileInputStreamChannel = null; 9 FileChannel fileOutputStreamChannel = null; 10 long start = 0; 11 12 try { 13 //查看耗時 14 start = System.currentTimeMillis(); 15 16 //寫入 17 fileInputStream = new FileInputStream("D:/DataTestFile/1.zip"); 18 //讀取到 19 fileOutputStream = new FileOutputStream("D:/DataTestFile/2.zip"); 20 21 //使用通道進行文件傳輸 22 //在傳輸前先獲取傳輸通道channel 23 fileInputStreamChannel = fileInputStream.getChannel(); 24 fileOutputStreamChannel = fileOutputStream.getChannel(); 25 26 //將數據寫入緩衝區 --> 開闢緩衝區容量 --> 後使用通道傳輸 27 ByteBuffer buf = ByteBuffer.allocate(1024); 28 29 //將通道中的數據送入緩衝區 數據爲空時跳出循環 30 while(fileInputStreamChannel.read(buf) != -1){ 31 //切換讀寫模式 32 buf.flip(); 33 //讀出緩衝區的數據寫入通道中 34 fileOutputStreamChannel.write(buf); 35 //清空緩衝區 36 buf.clear(); 37 } 38 39 40 } catch (FileNotFoundException e) { 41 e.printStackTrace(); 42 } catch (IOException e) { 43 e.printStackTrace(); 44 } 45 //最終須要執行的步驟 須要關閉流 和通道 46 finally { 47 //寫入流關閉 48 if (fileInputStream != null){ 49 try { 50 fileInputStream.close(); 51 } catch (IOException e) { 52 e.printStackTrace(); 53 } 54 } 55 //讀出流關閉 56 if (fileOutputStream != null){ 57 try { 58 fileOutputStream.close(); 59 } catch (IOException e) { 60 e.printStackTrace(); 61 } 62 } 63 if (fileInputStreamChannel != null){ 64 try { 65 fileInputStreamChannel.close(); 66 } catch (IOException e) { 67 e.printStackTrace(); 68 } 69 } 70 //讀出通道關閉 71 if (fileOutputStreamChannel != null){ 72 try { 73 fileOutputStreamChannel.close(); 74 } catch (IOException e) { 75 e.printStackTrace(); 76 } 77 } 78 //查看耗時 79 long end = System.currentTimeMillis(); 80 System.out.println("總共耗時:"+(end-start)); 81 } 82 83 84 }
1 public FileInputStream(String name) throws FileNotFoundException { 2 this(name != null ? new File(name) : null); 3 } 4 5 6 7 8
//獲取本地文件 9 public File(String pathname) { 10 if (pathname == null) { 11 throw new NullPointerException(); 12 } 13 this.path = fs.normalize(pathname); 14 this.prefixLength = fs.prefixLength(this.path); 15 }
1 /* 2 * 經過直接緩衝區的方式進行傳輸數據 3 * 經過使用映射文件的方式MappedByteBuffer傳輸 4 * */ 5 @Test 6 public void Driect(){ 7 8 FileChannel fileInChannel = null; 9 FileChannel fileOutChannel = null; 10 MappedByteBuffer mappedInByteBuffer = null; 11 MappedByteBuffer mappedOutByteBuffer = null; 12 long start = 0; 13 14 try { 15 //耗時查詢 16 start = System.currentTimeMillis(); 17 18 fileInChannel = FileChannel.open(Paths.get("D:/DataTestFile/1.zip"), StandardOpenOption.READ,StandardOpenOption.WRITE); 19 fileOutChannel = FileChannel.open(Paths.get("D:/DataTestFile/2.zip"), StandardOpenOption.READ, StandardOpenOption.WRITE,StandardOpenOption.CREATE); 20 21 //使用內存映射文件 ,杜絕非直接緩存區中的經過用戶態 和核心態的相互複製影響性能的問題 22 //直接經過本地映射文件。可是一旦傳輸後,不歸程序所管理 23 mappedInByteBuffer = fileInChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileInChannel.size()); 24 mappedOutByteBuffer = fileOutChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileInChannel.size()); 25 26 //直接對緩衝區進行讀寫操做 27 //定義一個數組,將映射文件的數據存入其中 28 byte[] bt = new byte[mappedInByteBuffer.limit()]; 29 //先從本地映射文件中讀取 後寫入傳輸 30 mappedInByteBuffer.get(bt); 31 mappedOutByteBuffer.put(bt); 32 33 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 finally { 38 if (fileInChannel != null){ 39 try { 40 fileInChannel.close(); 41 } catch (IOException e) { 42 e.printStackTrace(); 43 } 44 } 45 if (fileOutChannel != null){ 46 try { 47 fileOutChannel.close(); 48 } catch (IOException e) { 49 e.printStackTrace(); 50 } 51 } 52 53 //耗時結束查詢 54 long end = System.currentTimeMillis(); 55 System.out.println("總共耗時:"+(end-start)); 56 57 }
1 package com.cllover.nio; 2 3 import org.junit.Test; 4 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7 import java.io.RandomAccessFile; 8 import java.nio.ByteBuffer; 9 import java.nio.channels.FileChannel; 10 11 /* 12 * @Author chengpunan 13 * @Description //TODO 18609 14 * @Date 7:29 PM 7/25/2020 15 * @Param 16 * @return 17 * 18 * 分散讀寫和彙集讀寫測試類 19 * Disperse:分散讀寫 20 * gather: 彙集讀寫 21 **/ 22 public class DisperseAndGather { 23 24 // 分散讀寫 將通道中的數據分散到緩衝區中, 25 @Test 26 public void Disperse(){ 27 RandomAccessFile randomAccessFile = null; 28 FileChannel randomAccessFileChannel = null; 29 30 try { 31 //隨機訪問文件流以RW形式訪問某文件 32 randomAccessFile = new RandomAccessFile("D:/DataTestFile/1.txt","rw"); 33 34 //獲取通道 35 randomAccessFileChannel = randomAccessFile.getChannel(); 36 37 //開闢兩個緩衝區 38 ByteBuffer byteBuffer100 = ByteBuffer.allocate(100); 39 ByteBuffer byteBuffer200 = ByteBuffer.allocate(200); 40
//數值初始化:存入兩個緩衝區的數據
41 //分散讀取 42 ByteBuffer[] byteBuffer = {byteBuffer100,byteBuffer200}; 43 44 //存入讀取通道 45 randomAccessFileChannel.read(byteBuffer); 46 47 for (ByteBuffer bf: byteBuffer) { 48 bf.flip(); //切換讀寫方式 49 } 50 //轉換成字符串 51 //public String(byte bytes[], int offset, int length) 52 System.out.println(new String(byteBuffer[0].array(),0,byteBuffer[0].limit())); 53 System.out.println("----------------------------------"); 54 System.out.println(new String(byteBuffer[1].array(),0,byteBuffer[1].limit())); 55 56 } catch (FileNotFoundException e) { 57 e.printStackTrace(); 58 } catch (IOException e) { 59 e.printStackTrace(); 60 } 61 finally { 62 if (randomAccessFile != null){ 63 try { 64 randomAccessFile.close(); 65 } catch (IOException e) { 66 e.printStackTrace(); 67 } 68 } 69 if (randomAccessFileChannel != null){ 70 try { 71 randomAccessFileChannel.close(); 72 } catch (IOException e) { 73 e.printStackTrace(); 74 } 75 } 76 if (randomAccessFile != null){ 77 try { 78 randomAccessFile.close(); 79 } catch (IOException e) { 80 e.printStackTrace(); 81 } 82 } 83 } 84 85 } 86 87 }
將單獨兩個開闢的緩衝區,存入數組之中。存入通道後,用foreach循環遍歷index[0]和index[1]緩衝區上的內容,並進行寫入。java
1 //分散讀取:數組初始化 2 ByteBuffer[] byteBuffer = {byteBuffer100,byteBuffer200}; 3 4 //存入讀取通道 5 randomAccessFileChannel.read(byteBuffer); 6 7 for (ByteBuffer bf: byteBuffer) { 8 bf.flip(); //切換讀寫方式 9 }
1 //彙集寫入 2 RandomAccessFile randomAccessFile1 = new RandomAccessFile("D:/DataTestFile/2.txt", "rw"); 3 FileChannel channel = randomAccessFile1.getChannel(); 4 //將所有內容。將上段代碼紅色部分,存入數組中的數據直接經過通道寫入另外一個文件中 5 channel.write(byteBuffer);