java基礎知識——網路編程、IO流

來源:互聯網
上載者:User

java基礎知識——網路編程、IO流
IO流

位元組流:處理位元組資料的流對象,電腦中最小資料單元就是位元組。InputStream OutputStream

字元流:字元編碼問題,將位元組流和編碼錶封裝成對象就是字元流。Reader Write

讀、寫都會發生 IO 異常。io 異常的處理方式 :io 一定要寫 finally。fw.flush();//重新整理緩衝區,fw.close();//關閉流。

IO  中的使用到了一個設計模式: 裝飾設計模式。裝飾設計模式解決:對一組類進行功能的增強。封裝:寫一個類(封裝類)對被封裝對象進行封裝;* 1、封裝類和被封裝對象要實現同樣的介面;* 2、封裝類要持有一個被封裝對象;* 3、封裝類在實現介面時,大部分方法是靠調用被封裝對象來實現的,對於需要修改的方法我們自己實現;
字元流Reader : 用於讀取字元流的抽象類別。子類必須實現的方法只有 read(char[], int, int) 和 close()。 Writer : 寫入字元流的抽象類別。子類必須實現的方法僅有 write(char[], int, int)、flush() 和 close()。位元組流

InputStream、OutputStream

BufferedWriter :是給字元輸出資料流提高效率用的,那就意味著,緩衝區對象建立時,必須要先有流對象。明確要提高具體的流對象的效率。FileWriter fw = new FileWriter("bufdemo.txt");BufferedWriter bufw = new BufferedWriter(fw); // 讓緩衝區和指定流相關聯。for(int x=0; x<4; x++){bufw.write(x+"abc");bufw.newLine();  // 寫入一個分行符號,這個分行符號可以依據平台的不同寫入不同的分行符號。bufw.flush();//對緩衝區進行重新整理,可以讓資料到目的地中。}bufw.close(); // 關閉緩衝區,其實就是在關閉具體的流。-----------------------------BufferedReader :FileReader fr = new FileReader("bufdemo.txt");BufferedReader bufr = new BufferedReader(fr);String line = null;while((line=bufr.readLine())!=null){ e //readLine  方法返回的時候是不帶分行符號的。System.out.println(line);}bufr.close();-----------------------------//記住,只要一讀取鍵盤錄入,就用這句話。BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));//輸出到控制台String line = null;while((line=bufr.readLine())!=null){if("over".equals(line))break;51 / 65bufw.write(line.toUpperCase());//將輸入的字元轉成大寫字元輸出bufw.newLine();bufw.flush();}bufw.close();bufr.close();

流的操作規律:

1 ,明確源和目的。
資料來源:就是需要讀取,可以使用兩個體系:InputStream、Reader;
資料匯:就是需要寫入,可以使用兩個體系:OutputStream、Writer;

2 ,操作的資料是否是純文字資料?
如果是:資料來源:Reader
資料匯:Writer
如果不是:資料來源:InputStream
資料匯:OutputStream

3 ,雖然確定了一個體系,但是該體系中有太多的對象,到底用哪個呢?
明確操作的資料裝置。
資料來源對應的裝置:硬碟(File),記憶體(數組),鍵盤(System.in)
資料匯對應的裝置:硬碟(File),記憶體(數組),控制台(System.out)。 4 ,需要在基本操作上附加其他功能嗎?比如緩衝。
如果需要就進行裝飾。File類將檔案系統中的檔案和檔案夾封裝成了對象。提供了更多的屬性和行為可以對這些檔案和檔案夾
進行操作。這些是流對象辦不到的,因為流只操作資料。
createNewFile() 、mkdir()、getAbsolutePath()遞迴

使用方式:功能內部又用到該功能,但是傳遞的參數值不確定。

遞迴的注意事項:
1:一定要定義遞迴的條件。
2:遞迴的次數不要過多。容易出現 StackOverflowError 棧記憶體溢出 錯誤。
其實遞迴就是在棧記憶體中不斷的載入同一個函數。

Java遞迴演算法的小例子 求1+2+3…+1000 和

 public class Test1 {int sum=0;int a=1;public void sum(){   sum+=a;   a++;   if(a<=1000)   {sum();//調用自身實現遞迴   }}public static void main(String[] args) {   Test1 test=new Test1();   test.sum();   System.out.println("計算結果:"+test.sum+"!");}
擴充功能的流對象PrintStream : 列印流PrintStream m 可以操作目的:1:File 對象。2:字串路徑。3:位元組輸出資料流。 PrintWriter :該對象的目的地有四個:1:File 對象。2:字串路徑。3:位元組輸出資料流。4:字元輸出資料流。 PrintWriter out = new PrintWriter( new FileWriter(“out.txt”), true);//設定 true 後自動重新整理 System.in,System.out 這兩個標準的輸入輸出資料流,在 jvm 啟動時已經存在了。隨時可以使用。當
jvm 結束了,這兩個流就結束了。但是,當使用了顯示的 close 方法關閉時,這兩個流在提前結束了。SequenceInputStream : 序列流

作用就是將多個讀取流合并成一個讀取流實現資料合併。

合并原理:多個讀取流對應一個輸出資料流。
切割原理:一個讀取流對應多個輸出資料流。管道流

管道讀取流和管道寫入流可以像管道一樣對接上,管道讀取流就可以讀取管道寫入流寫入的資料。
注意 :需要加入多線程技術,因為單線程,先執行 read,會發生死結,因為 read 方法是阻塞式的,沒有資料的
read 方法會讓線程等待。

public static void main(String[] args) throws IOException{PipedInputStream pipin = new PipedInputStream();PipedOutputStream pipout = new PipedOutputStream();pipin.connect(pipout);new Thread(new Input(pipin)).start();new Thread(new Output(pipout)).start();}
對象序列化

待用資料不能被序列化,因為待用資料不在堆記憶體中;用transient關鍵字修飾變數,可以將非待用資料不進行序列化。

Serializable :用於啟始物件的序列化功能,可以強制讓指定類具備序列化功能,該介面中沒有成員,這是一
個標記介面。

ByteArrayInputStream : 源 : 記憶體
ByteArrayOutputStream :目的:記憶體。
這兩個流對象不涉及底層資源調用,操作的都是記憶體中數組,所以不需要關閉。

網路編程

連接埠:0-65535

//通過名稱(ip 字串 or 主機名稱)來擷取一個 ip 對象。InetAddress ip = InetAddress.getByName("www.baidu.com");//java.net.UnknownHostException
socket

為網路服務提供的一種機制,通訊的兩端都有 Socket,網路通訊其實就是 Socket 間的通訊,資料在兩個
Socket 間通過 IO 傳輸。

udp傳輸

資料一定要封裝到資料包中,資料包中包括目的地址、連接埠、資料等資訊。將 udp 封裝成對象,易於我們的使用,這個對象就是 DatagramSocket

發送端:

1,建立 udp 的 socket 服務,建立對象時如果沒有明確連接埠,系統會自動分配一個未被使用的連接埠。

2,明確要發送的具體資料。

3,將資料封裝成了資料包。

4,用 socket 服務的 send 方法將資料包發送出去。

5,關閉資源。

import java.net.*;class UdpSend{public static void main(String[] args)throws Exception {// 1 1 ,建立 p udp 的 的 t socket  服務。DatagramSocket ds = new DatagramSocket(8888);//指定傳送埠,不指定系統會隨機分配。// 2 2 ,明確要發送的具體資料。String text = "udp 傳輸示範 哥們來了";byte[] buf = text.getBytes();// 3 3 ,將資料封裝成了資料包。DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("10.1.31.127"),10000);// 4 4 ,用 t socket  服務的 d send  方法將資料包發送出去。ds.send(dp);// 5 5 ,關閉資源。ds.close();}}

p udp 的接收端:
1,建立 udp 的 socket 服務,必須要明確一個連接埠,作用在於,只有發送到這個連接埠的資料才是這個接收端可
以處理的資料。

2,定義資料包,用於儲存接收到資料。

3,通過 socket 服務的接收方法將收到的資料存放區到資料包中。

4,通過資料包的方法擷取資料包中的具體資料內容,比如 ip、連接埠、資料等等。

5,關閉資源。

class UdpRece {public static void main(String[] args) throws Exception{// 1 1 ,建立 p udp 的 的 t socket  服務。DatagramSocket ds = new DatagramSocket(10000);// 2 2 ,定義資料包,用於儲存接收到資料。先定義位元組數組,資料包會把資料存放區到位元組數組中。byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);// 3 3 ,通過 t socket  服務的接收方法將收到的資料存放區到資料包中。ds.receive(dp);//該方法是阻塞式方法。// 4 4 ,通過資料包的方法擷取資料包中的具體資料內容,比如  ip ,連接埠,資料等等。String ip = dp.getAddress().getHostAddress();int port = dp.getPort();String text = new String(dp.getData(),0,dp.getLength());//將位元組數組中的有效部分轉成字串。System.out.println(ip+":"+port+"--"+text);// 5 5 ,關閉資源。ds.close();}}
tcp傳輸

兩個端點的建立串連後會有一個傳輸資料的通道,這通道稱為流,而且是建立在網路基礎上的流,
稱之為 socket 流。該流中既有讀取,也有寫入。

TCP 用戶端 :

1,建立 tcp 的 socket 服務,最好明確具體的地址和連接埠。這個對象在建立時,就已經可以對指定 ip 和連接埠
進行串連(三向交握)。

2,如果串連成功,就意味著通道建立了,socket 流就已經產生了。只要擷取到 socket 流中的讀取流和寫入
流即可,只要通過 getInputStream 和 getOutputStream 就可以擷取兩個流對象。

3,關閉資源。

import java.net.*;import java.io.*;//需求:用戶端給伺服器端發送一個資料。class TcpClient{public static void main(String[] args) throws Exception{Socket s = new Socket("10.1.31.69",10002);OutputStream out = s.getOutputStream();// 擷取了 t socket  流中的輸出資料流對象。out.write("tcp 示範,哥們又來了!".getBytes());s.close();}}

TCP 服務端:

1,建立服務端 socket 服務,並監聽一個連接埠。

2,服務端為了給用戶端提供服務,擷取用戶端的內容,可以通過 accept 方法擷取串連過來的用戶端對象。

3,可以通過擷取到的 socket 對象中的 socket 流和具體的用戶端進行通訊。

4,如果通訊結束,關閉資源。注意:要先關用戶端,再關服務端。

class TcpServer{public static void main(String[] args) throws Exception{62 / 65ServerSocket ss = new ServerSocket(10002);//建立服務端的 socket 服務Socket s = ss.accept();//擷取用戶端對象String ip = s.getInetAddress().getHostAddress();System.out.println(ip+".....connected");// 可以通過擷取到的 socket 對象中的 socket 流和具體的用戶端進行通訊。InputStream in = s.getInputStream();//讀取用戶端的資料,使用用戶端對象的 socket 讀取流byte[] buf = new byte[1024];int len = in.read(buf);String text = new String(buf,0,len);System.out.println(text);// 如果通訊結束,關閉資源。 注意:要先關用戶端,在關服務端。s.close();ss.close();}}
反射技術

反射技術可以對一個類進行解剖。

基本步驟:
1 、 獲得 s Class 對象 ,就是擷取到指定的名稱的位元組碼檔案對象 。
2 、 執行個體化對象, 獲得類的屬性、方法或建構函式。
3、訪問屬性、調用方法、調用建構函式建立對象Regex常見操作:
1,匹配:其實用的就是 String 類中的 matches 方法。
String reg = “[1-9][0-9]{4,14}”;
boolean b = qq. matches(reg);//將正則和字串關聯對字串進行匹配。

2,切割:其實用的就是 String 類中的 split 方法。

3,替換:其實用的就是 String 類中的 replaceAll();

4,擷取:
1),先要將Regex編譯成正則對象。使用的是 Pattern 中靜態方法 compile(regex);

2),通過 Pattern 對象擷取 Matcher 對象。
Pattern 用於描述Regex,可以對Regex進行解析。
而將規則操作字串,需要從新封裝到匹配器對象 Matcher 中。
然後使用 Matcher 對象的方法來操作字串。
如何擷取匹配器對象呢?
通過 Pattern 對象中的 matcher 方法。該方法可以正則規則和字串想關聯。並返回匹配器對象。

3),使用 Matcher 對象中的方法即可對字串進行各種正則操作。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.