Java IO程式設計
Java IO
Java有非常豐富的IO介面,從流型別可劃分為位元組流和字元流,從流操作的位置可劃分為網路IO和本地IO。
- 本地IO
-
- 本地IO時,普通IO和BIO最為常用,BIO較普通IO有更豐富的流操作元件,而NIO、AIO對於本地IO來說反而會在效率上大打折扣
-
- 那麼buffer有什麼作用呢?它會在記憶體中開闢一塊緩衝區,用於優化對流的操作,讀流時:不間斷地從裝置讀到緩衝區中,同時對緩衝區進行間斷(每次1024位元組)地讀取操作,速度加快。寫流時:先將流間斷(每次1024位元組)地寫入到緩衝區中,再統一對裝置寫入,速度加快,mark/reset就是通過這種方式實現的
- 網路IO
-
- 網路IO時,普通IO效率最低,BIO效率較普通IO更高,但BIO每個連線都需要起一個執行緒,而NIO通過selector完美地解決了這個問題,AIO是併發量較大網路IO的解決方案,它的內部其實是通過執行緒池去併發處理各個請求,那麼是不是意味著普通BIO和NIO中加入執行緒池就可以替代AIO呢?毋庸置疑不是的,BIO 和 NIO 的使用中加執行緒池不是什麼好主意,因為有channel的限制,所以AIO這套框架並沒有白做。
-
- IO:普通的IO,每次操作stream,都需要和磁碟互動,效率最低
-
- BIO:一個連線一個執行緒,客戶端有連線請求時伺服器端就需要啟動一個執行緒進行處理,如果這個連線不做任何事情會造成不必要的執行緒開銷,當然可以通過執行緒池機制改善
-
- NIO:一個請求一個執行緒,通過selector對多個channel監聽,並統一響應和處理,selector輪詢到連線有I/O請求時才啟動一個執行緒進行處理
-
- AIO:一個請求一個執行緒,客戶端的I/O請求都是由OS先完成(將IO直接讀到緩衝區)了再通知伺服器應用去啟動執行緒進行處理,但沒有selector的概念,併發情況下效率高於NIO
- 以下是幾種IO的技術架構圖
- BIO
- NIO
- AIO
- NIO和BIO的區別
接下來上程式碼
- 普通IO
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.PushbackInputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Date;
import java.util.zip.ZipInputStream;
/**
* 位元組IO
*/
public class IOByteStream {
public static void main(String[] args) {
File fin = new File("C:\\Users\\Administrator\\Desktop\\test\\J0.java");
File fout = new File("C:\\Users\\Administrator\\Desktop\\test\\J1.java");
level1(fin, fout);
level2(fin);
level4Object(fout);
}
public static void level1(File fin, File fout) {
try (
FileInputStream fis = new FileInputStream(fin);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(fout, false);
BufferedOutputStream bos = new BufferedOutputStream(fos);
) {
System.out.println("stream markSupported - " + fis.markSupported());
System.out.println("buffer markSupported - " + bis.markSupported());
//mark後讀取超過readlimit位元組資料,mark標記就會失效
bis.mark(40960);
byte[] b = new byte[1024];
int i = 0;
while ((i = bis.read(b)) > 0) {
bos.write(b, 0, i);
}
bos.flush();
bis.reset();
byte[] b2 = new byte[1024];
int i2 = 0;
while ((i2 = bis.read(b2)) > 0) {
bos.write(b2, 0, i2);
}
bos.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void level2(File f) {
try (
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
PushbackInputStream pbis = new PushbackInputStream(bis);
DataInputStream dis = new DataInputStream(pbis);
) {
int s1 = dis.read();System.out.println(s1);
pbis.unread(s1);
int s2 = dis.read();System.out.println(s2);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void level3Zip(File f) {
try (
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
ZipInputStream zis = new ZipInputStream(bis);
PushbackInputStream pbis = new PushbackInputStream(zis);
DataInputStream dis = new DataInputStream(pbis);
) {
} catch (Exception e) {
e.printStackTrace();
}
}
public static void level4Object(File f) {
try (
FileOutputStream fos = new FileOutputStream(f, true);
BufferedOutputStream bos = new BufferedOutputStream(fos);
ObjectOutputStream oos = new ObjectOutputStream(bos);
) {
Object o = new Object();
oos.writeObject(o);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 字元IO
*/
class IOCharStream {
public static void main(String[] args) {
File f = new File("C:\\Users\\Administrator\\Desktop\\test\\J0.java");
File f2 = new File("C:\\Users\\Administrator\\Desktop\\test\\J1.java");
level2(f2);
level1(f);
}
public static void level1(File f) {
try (
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
) {
br.lines().forEach(line -> System.out.println(line));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void level2(File f) {
try (
FileOutputStream fos = new FileOutputStream(f, true);
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(osw, true);
) {
pw.print("abcs");
pw.println("ab");
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* NIO讀寫
*/
class NIOStream {
public static void main(String[] args) {
File fin = new File("C:\\Users\\Administrator\\Desktop\\test\\J0.java");
File fout = new File("C:\\Users\\Administrator\\Desktop\\test\\J1.java");
level1(fin, fout);
}
public static void level1(File fin, File fout) {
try (
RandomAccessFile fis = new RandomAccessFile(fin, "rw");
FileChannel channelIn = fis.getChannel();
RandomAccessFile fos = new RandomAccessFile(fout, "rw");
FileChannel channelOut = fos.getChannel();
) {
Charset charset = Charset.forName("UTF-8");//Java.nio.charset.Charset處理了字元轉換問題。它通過構造CharsetEncoder和CharsetDecoder將字元序列轉換成位元組和逆轉換。
CharsetDecoder decoder = charset.newDecoder();
MappedByteBuffer byteBufferIn = channelIn.map(FileChannel.MapMode.READ_WRITE, 0, channelIn.size());
channelOut.write(byteBufferIn);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 三種流之間的對比
*/
class CompareWithStream {
public static void main(String[] args) {
File fin = new File("C:\\Users\\Administrator\\Desktop\\test\\J0.java");
File fout = new File("C:\\Users\\Administrator\\Desktop\\test\\J1.java");
level1NoBuffer(fin, fout); // 普通IO 讀寫5000次 耗時12毫秒
level1buffer(fin, fout); // 緩衝IO 讀寫5000次 耗時13毫秒
level1NIO(fin, fout); // NIO 讀寫5000次 耗時70毫秒
}
public static void level1NoBuffer(File fin, File fout) {
try (
FileInputStream fis = new FileInputStream(fin);
FileOutputStream fos = new FileOutputStream(fout, false);
) {
byte[] b = new byte[1024];
long time3 = new Date().getTime();
for (int i = 0; i < 5000; i++) {
int c = 0;
while ((c = fis.read(b)) > 0) {
fos.write(b, 0, c);
}
fos.flush();
}
long time4 = new Date().getTime();
System.out.println("普通IO:" + (time4 - time3));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void level1buffer(File fin, File fout) {
try (
FileInputStream fis = new FileInputStream(fin);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(fout, false);
BufferedOutputStream bos = new BufferedOutputStream(fos);
) {
byte[] b = new byte[1024];
long time1 = new Date().getTime();
for (int i = 0; i < 5000; i++) {
int c = 0;
while ((c = bis.read(b)) > 0) {
bos.write(b, 0, c);
}
bos.flush();
}
long time2 = new Date().getTime();
System.out.println("緩衝IO:" + (time2 - time1));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void level1NIO(File fin, File fout) {
try (
RandomAccessFile fis = new RandomAccessFile(fin, "rw");
FileChannel channelIn = fis.getChannel();
RandomAccessFile fos = new RandomAccessFile(fout, "rw");
FileChannel channelOut = fos.getChannel();
) {
long time5 = new Date().getTime();
for (int i = 0; i < 5000; i++) {
MappedByteBuffer byteBufferIn = channelIn.map(FileChannel.MapMode.READ_WRITE, 0, channelIn.size());
channelOut.write(byteBufferIn);
}
long time6 = new Date().getTime();
System.out.println("磁碟對映IO:" + (time6 - time5));
} catch (Exception e) {
e.printStackTrace();
}
}
}
- BIO
服務端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服務端
*/
public final class ServerNormal {
//預設的埠號
private static int DEFAULT_PORT = 12345;
//單例的ServerSocket
private static ServerSocket server;
//根據傳入引數設定監聽埠,如果沒有引數呼叫以下方法並使用預設值
public static void start() throws IOException{
//使用預設值
start(DEFAULT_PORT);
}
//這個方法不會被大量併發訪問,不太需要考慮效率,直接進行方法同步就行了
public synchronized static void start(int port) throws IOException{
if(server != null) return;
try{
//通過建構函式建立ServerSocket
//如果埠合法且空閒,服務端就監聽成功
server = new ServerSocket(port);
System.out.println("PID:"+ Thread.currentThread().getId()+ " 伺服器已啟動,埠號:" + port);
//通過無限迴圈監聽客戶端連線
//如果沒有客戶端接入,將阻塞在accept操作上。
while(true){
Socket socket = server.accept();
//當有新的客戶端接入時,會執行下面的程式碼
//然後建立一個新的執行緒處理這條Socket鏈路
new ServerHandler(socket).run();
}
}finally{
//一些必要的清理工作
if(server != null){
System.out.println("伺服器已關閉。");
server.close();
server = null;
}
}
}
public static void main(String[] args) {
try {
start();
System.out.println("I have been out.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
相關推薦
Java IO 程式設計(BIO、NIO、AIO完整例項程式碼)
本文會從傳統的BIO到NIO再到AIO自淺至深介紹,並附上程式碼講解。
原始碼地址: https://github.com/kkman2008/java-IO.git
下面程式碼中會使用這樣一個
Java IO程式設計
Java IO
Java有非常豐富的IO介面,從流型別可劃分為位元組流和字元流,從流操作的位置可劃分為網路IO和本地IO。
本地IO
本地IO時,普通IO和BIO
java IO程式設計(一)檔案操作類:File
學習過程中某個知識點長時間不用老是忘記,在此記錄,下次忘記容易複習。
在java.io包中,如果要進行檔案自身的操作(例如:建立、刪除等),只能依靠java.io.File類完成。File類中的常用方法在下表中列出
File
[面試要點]java io程式設計
java io 簡介
慣例先祭出一張圖
[1]輸入位元組流InputStream:InputStream 是所有的輸入位元組流的父類,它是一個抽象類;ByteArrayInputStream、StringBufferInputStream、FileInp
Java IO程式設計[轉載]
什麼是IO
IO(Input/Output)是計算機輸出/輸出的介面。Java的核心庫java.io提供了全面的IO介面,包括:檔案讀寫,標準裝置輸出等等。Java中IO是以流為基礎進行輸入輸出的,所有資料被序列化寫入輸出流,或者從輸入流讀入。此外,Java也對塊傳輸
Java IO程式設計——File檔案操作類
在Java語言裡面提供有對於檔案作業系統操作的支援,而這個支援就在java.io.File類中進行了定義,也就是說在整個java.io包裡面,File類是唯一 一個與檔案本身操作(建立、刪除、重新命名等)有關的類,而如果要想進行File類的操作,必須要提供有完整的路徑,而後可以呼叫相
Java IO程式設計——字元流與位元組流
在java.io包裡面File類是唯一 一個與檔案本身有關的程式處理類,但是File只能夠操作檔案本身而不能夠操作檔案的內容,或者說在實際的開發之中IO操作的核心意義在於:輸入與輸出操作。而對於程式而言,輸入與輸出可能來自於不同的環境,例如:通過電腦連線伺服器上進行瀏覽的時候,實際上此時客戶端發出了一個資訊,
Java 網路IO程式設計
什麼是Socket
Socket是應用層與TCP/IP協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對使用者來說,一組簡單的介面就是全部,讓Socket去組織資料,以符合指定的協議。
如下
Java基礎篇-File IO程式設計
如果自學時候 對於IO可能會有恐懼感
如果要學好IO 必須清楚抽象類? 為什麼
IO的操作部分,重點掌握兩個程式碼模型
IO核心組成: 五個類: File OutputStream InputStream Writer Reader
File類詳解 在java.io當中 File類是唯一一個與檔案本身
33 JAVA程式設計思想——JAVA IO File類
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
 
JAVA入門到精通-第46講-IO程式設計.記事本開發
IO程式設計-記事本開發
fis.read(bytes)
位元組陣列:
通過fis把檔案裡面的1800個字元,儘可能的讀,
最多讀1024個。記錄一下,0-1024記錄到bytes;
再去讀的首,fis.read試圖1024個位元組,不夠了,
JAVA入門到精通-第45講-IO程式設計
image1=ImageIO.read(new File("bomb_1.gif"));
圖片拷貝:
輸入流和輸出流同時要用的問題:
圖片讀入到記憶體;
寫入,輸出到某個檔案;
二進位制檔案,位元組流完成;
FileInputStream fis
JAVA入門到精通-第44講-IO程式設計
//FileOutputStream的使用
準備把它輸出到d:\\ss.txt 檔案,
檔案不存在直接建立;
如果存在,可能會被覆蓋;
//位元組流
FileOutputStream fos=null;
//輸出-Output-離開記憶體-
Java程式設計思想(五)第18章-Java IO系統
目錄:
1 File類
File(檔案)類這個名字有一定的誤導性;我們可能會認為它指代的是檔案,實際上卻並非如此。它既能代表一個特定檔案的名稱,又能代表一個目錄下的一組檔案的名稱。實際上,FilePath(檔案路徑)對這個類來說是更好的名字。
如果它指的
Java 高階程式設計-IO程式設計,物件序列化&反序列化
1. 物件序列化基本概念
2. 序列化與反序列化
3. transient關鍵字
學習阿里雲大學零基礎學Java系列 Java高階程式設計
Java 高階程式設計-IO操作深入
1. 字元編碼
2. 記憶體操作流
3. 管道流
4. RandomAccessFile隨機儲存類
學習阿里雲大學零基礎學Java系列 Java高階程式設計
1. 字元編碼
在計算機的世界裡面只認
Java 高階程式設計-IO位元組流與字元流
1. 簡介
2. 位元組輸出流OutputStream
3. 位元組輸入流InputStream
4. 字元輸出流Writer
5. 字元輸入流Reader
6. 位元組流與字元流的區別
7. 轉
34 JAVA程式設計思想——JAVA IO 流典型應用
34.JAVA程式設計思想——JAVA IO 流典型應用儘管庫記憶體在大量IO 流類,可通過多種不同的方式組合到一起,但實際上只有幾種方式才會經常用到。然而,必須小心在意才能得到正確的組合。下面這個相當長的例子展示了典型IO 配置的建立與使用,可在寫自己的程式碼時將其作為一個參
Java 網路IO程式設計總結(BIO、NIO、AIO均含完整例項程式碼)
第一段內容轉載自:http://blog.51cto.com/stevex/1284437
先來個例子理解一下概念,以銀行取款為例:
同步 : 自己親自出馬持銀行卡到銀行取錢(使用同步IO時,Java自己處理IO讀寫)。
非同步
Java基礎:java網路程式設計IO總結(BIO、NIO、AIO)
1.基本概念
在Java網路通訊中,最基本的概念就是Socket程式設計了。Socket又稱“套接字” 向網路發出請求或者應答網路請求。
Socket 和ServerSocket類庫位於 Java.net 包中。ServerSocket用於伺服器端,Socket是建立網路連線時使用的