文章目錄
每日一考和複習
每日一考
- 說明流的三種分類方式
1.流向:輸入流、輸出流
2.數據單位:字節流、字符流
3.流的角色:節點流、處理流
- 寫出4個IO流中的抽象基類,4個文件流,4個緩衝流
1.InputStream
OutputStream
Writer
Reader
2.FileInputStream
FileOutputStream
FileWriter
FileReader
3.BufferedInputStream
BufferedOutputStream
BufferedWriter
BufferedReader
- 字節流與字符流的區別與使用情境
1.字節流一般用於傳輸文本文件
2.字符流一般用於傳輸文本文件
- 使用緩衝流實現a.jpg文件複製爲b.jpg文件的操作
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
File file1 = new File("a.jpg");
File file2 = new File("b.jpg");
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 轉換流是哪兩個類,分別的作用是什麼?請分別創建兩個類的對象
InputStreamWriter:將輸入的字節流轉換爲輸入的字符流,解碼
InputStreamReader isr = new InputStreamReader(new FileInputStream(“a.txt”),”utf-8”);
OutputStreamReader:將輸出的字符流轉換爲輸出的字節流,編碼
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“b.txt”),”gbk”);
複習
day26的學習內容
IO流(接day26)
對象流
ObjectInputStream
ObjectOutputStream
-
作用:用於存儲和讀取基本數據類型數據或對象的處理流。它的強大之處就是可以把Java中的對象寫入到數據源中,也能把對象從數據源中還原回來;要求對象是可序列化的
-
序列化機制:
對象序列化機制允許把內存中的Java對象轉換成平臺無關的二進制流,從而允許把這種二進制流持久地保存在磁盤上,或通過網絡將這種二進制流傳輸到另一個網絡節點;當其它程序獲取了這種二進制流,就可以恢復成原來的Java對象 -
要想一個java對象是可序列化的,需要滿足以下要求
1.需要實現接口:Serializable
2.當前類提供一個全局常量:serialVersionUID
3.除了當前Person類需要實現Serializable接口之外,還必須保證其內部所有屬性也必須是可序列化的。
(默認情況下,基本數據類型可序列化)
ObjectOutputStream和ObjectInputStream不能序列化static和transient修飾的成員變量
序列化過程:將內存中的java對象保存到磁盤中或通過網絡傳輸出去
使用ObjectOutputStream
實現
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new String("我愛你三千遍"));
oos.flush();//刷新操作
oos.writeObject(new Person("姓名", 23));
oos.flush();
oos.writeObject(new Person("test", 23, 1001, new Account(5000)));
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
反序列化:將磁盤文件中的對象還原爲內存中的一個java對象
使用ObjectInputStream
來實現
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Object obj = ois.readObject();
String str = (String) obj;
Person p = (Person) ois.readObject();
Person p1 = (Person) ois.readObject();
System.out.println(str);
System.out.println(p);
System.out.println(p1);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
RandomAccessFile
-
RandomAccessFile直接繼承於java.lang.Object類,實現了DataInput和DataOutput接口
-
RandomAccessFile既可以作爲一個輸入流,又可以作爲一個輸出流
-
如果RandomAccessFile作爲輸出流時,寫出到的文件如果不存在,則在執行過程中自動創建
如果寫出到的文件存在,則會對原有文件內容進行覆蓋。(默認情況下,從頭覆蓋,也可以設置開始的位置) -
可以通過相關的操作,實現RandomAccessFile“插入”數據的效果
RandomAccessFile raf1 = null;
RandomAccessFile raf2 = null;
try {
raf1 = new RandomAccessFile(new File("test.jpg"), "r");// 可讀
raf2 = new RandomAccessFile(new File("test1.jpg"), "rw");// 可讀可寫
byte[] buffer = new byte[1024];
int len;
while ((len = raf1.read(buffer)) != -1) {
raf2.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (raf1 != null) {
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (raf2 != null) {
try {
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用RandomAccessFile實現數據的插入效果
RandomAccessFile raf1 = null;
try {
raf1 = new RandomAccessFile("hello.txt", "rw");
raf1.seek(3);//將指針調到角標爲3的位置
//保存指針3後面的所有數據到StringBuilder中
StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
byte[] buffer = new byte[20];
int len;
while ((len = raf1.read(buffer)) != -1) {
builder.append(new String(buffer, 0, len));
}
//調回指針,寫入插入的數據
raf1.seek(3);
raf1.write("aaa".getBytes());
//將StringBuilder中的數據寫入到文件中
raf1.write(builder.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(raf1 != null) {
try {
raf1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
網絡編程
網絡編程概述
- 網絡編程的目的:
直接或間接地通過網絡協議與其它計算機實現數據交換,進行通訊 - 網絡編程中有兩個主要的問題:
- 如何準確地定位網絡上一臺或多臺主機;定位主機上的特定的應用
- 找到主機後如何可靠高效地進行數據傳輸
網絡通信要素概述
- 通信雙方地址
IP & 端口號 - 一定的規則
- OSI參考模型:模型過於理想化,未能在因特網上進行廣泛推廣
- TCP/IP參考模型(或TCP/IP協議):事實上的國際標準
通信要素1:IP和端口號
-
IP:唯一的標識 Internet 上的計算機(通信實體)
-
在Java中使用InetAddress類代表IP
-
IP分類:IPv4 和 IPv6 ;萬維網 和 局域網
-
域名: www.baidu.com/ www.mi.com/ www.sina.com/ www.jd.com/ www.vip.com
-
本地迴路地址:127.0.0.1 對應着:localhost
-
如何實例化InetAddress:兩個方法:
getByName(String host)
、getLocalHost()
兩個常用方法:getHostName()
/getHostAddress()
-
端口號:正在計算機上運行的進程
要求:不同的進程有不同的端口號
範圍:被規定爲一個 16 位的整數 0~65535 -
端口號與IP地址的組合得出一個網絡套接字:Socket
通信要素2:網絡協議
- 網絡通信協議
計算機網絡中實現通信必須有一些約定,即通信協議,對速率、傳輸代碼、代碼結構、傳輸控制步驟、出錯控制等制定標準 - 通信協議分層的思想
在制定協議時,把複雜成份分解成一些簡單的成份,再將它們復合起來。最常用的複合方式是層次方式,即同層間可以通信、上一層可以調用下一層,而與再下一層不發生關係。各層互不影響,利於系統的開發和擴展 - 傳輸層協議中有兩個非常重要的協議
TCP協議 和 UDP協議
TCP網絡編程
-
客戶端Socket的工作過程包含以下四個基本的步驟:
- 創建 Socket:根據指定服務端的 IP 地址或端口號構造 Socket 類對象。若服務器端響應,則建立客戶端到服務器的通信線路。若連接失敗,會出現異常
- 打開連接到 Socket 的輸入/出流: 使用
getInputStream()
方法獲得輸入流,使用getOutputStream()
方法獲得輸出流,進行數據傳輸 - 按照一定的協議對 Socket 進行讀/寫操作:通過輸入流讀取服務器放入線路的信息(但不能讀取自己放入線路的信息),通過輸出流將信息寫入線程
- 關閉 Socket:斷開客戶端到服務器的連接,釋放線路
-
服務器程序的工作過程包含以下四個基本的步驟:
- 調用
ServerSocket(int port)
:創建一個服務器端套接字,並綁定到指定端口上。用於監聽客戶端的請求 - 調用 accept():監聽連接請求,如果客戶端請求連接,則接受連接,返回通信套接字對象
- 調用該Socket類對象的
getOutputStream()
和getInputStream ()
:獲取輸出流和輸入流,開始網絡數據的發送和接收 - 關閉ServerSocket和Socket對象:客戶端訪問結束,關閉通信套接字
- 調用
TCP網絡編程練習一
客戶端發送信息給服務端,服務端將數據顯示在控制檯上
// 客戶端
Socket socket = null;
OutputStream os = null;
try {
//1.創建Socket對象,指明服務器端的ip和端口號
InetAddress inet = InetAddress.getByName("192.168.23.33");
socket = new Socket(inet, 8899);
//2.獲取一個輸出流,用於輸出數據
os = socket.getOutputStream();
//3.寫出數據的操作
os.write("你好,我是客戶端".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.資源的關閉
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//1.創建服務器端的ServerSocket,指明自己的端口號
ss = new ServerSocket(8899);
//2.調用accept()表示接收來自於客戶端的socket
socket = ss.accept();
//3.獲取輸入流
is = socket.getInputStream();
//4.讀取輸入流中的數據
//方式一:不建議這樣寫,可能會有亂碼
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
String str = new String(buffer, 0, len);
System.out.print(str);
}
//方式二
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[5];
int len;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
System.out.println(baos.toString());
System.out.println("收到了來自於:" + socket.getInetAddress().getHostAddress() + "的數據");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (baos != null) {
//5.關閉資源
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
TCP網絡編程練習二
客戶端發送文件給服務端,服務端將文件保存在本地
// 客戶端
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
os = socket.getOutputStream();
fis = new FileInputStream(new File("beauty.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 服務器端
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
try {
ss = new ServerSocket(9090);
socket = ss.accept();
is = socket.getInputStream();
fos = new FileOutputStream(new File("beauty1.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
TCP網絡編程練習三
從客戶端發送文件給服務端,服務端保存到本地。並返回“發送成功”給客戶端
// 客戶端
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
os = socket.getOutputStream();
fis = new FileInputStream(new File("beauty.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
//關閉數據的輸出
socket.shutdownOutput();
//接收來自於服務器端的數據,並顯示到控制檯上
is = socket.getInputStream();
baos = new ByteArrayOutputStream();
byte[] buffer1 = new byte[20];
int len1;
while ((len1 = is.read(buffer1)) != -1) {
baos.write(buffer, 0, len1);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os!=null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(baos!=null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 服務器端
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
OutputStream os = null;
try {
ss = new ServerSocket(9090);
socket = ss.accept();
is = socket.getInputStream();
fos = new FileOutputStream(new File("beauty2.jpg"));
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("圖片傳輸完成");
//服務器端給予客戶端反饋
os = socket.getOutputStream();
os.write("照片已收到!".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP網絡編程
// 發送方
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
String str = "我是UDP方式發送的數據";
byte[] data = str.getBytes();
InetAddress inet = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(data, 0, data.length, inet, 9090);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
socket.close();
}
}
// 接收方
DatagramSocket socket = null;
try {
socket = new DatagramSocket(9090);
byte[] buffer = new byte[100];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData(), 0, packet.getLength()));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
socket.close();
}
}
URL編程
-
URL(Uniform Resource Locator):統一資源定位符,它表示 Internet 上某一資源的地址
-
它是一種具體的URI,即URL可以用來標識一個資源,而且還指明瞭如何locate這個資源
-
通過 URL 我們可以訪問 Internet 上的各種網絡資源,比如最常見的 www,ftp 站點。瀏覽器通過解析給定的 URL 可以在網絡上查找相應的文件或其他資源
-
URL的基本結構由5部分組成:
<傳輸協議>://<主機名>:<端口號>/<文件名>#片段名?參數列表 -
爲了表示URL,java.net 中實現了類 URL,以下是該類的常用方法
try {
URL url = new URL("http://localhost:8080/examples/beauty.jpg?username=Tom");
//public String getProtocol( ) 獲取該URL的協議名
System.out.println(url.getProtocol());
//public String getHost( ) 獲取該URL的主機名
System.out.println(url.getHost());
//public String getPort( ) 獲取該URL的端口號
System.out.println(url.getPort());
//public String getPath( ) 獲取該URL的文件路徑
System.out.println(url.getPath());
//public String getFile( ) 獲取該URL的文件名
System.out.println(url.getFile());
//public String getQuery( ) 獲取該URL的查詢名
System.out.println(url.getQuery());
} catch (MalformedURLException e) {
e.printStackTrace();
}
通過URL編程下載圖片
HttpURLConnection urlConnection = null;
InputStream is = null;
FileOutputStream fos = null;
try {
URL url = new URL("http://localhost:8080/examples/beauty.jpg");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
is = urlConnection.getInputStream();
fos = new FileOutputStream("beauty3.jpg");
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
System.out.println("下載完成");
} catch (IOException e) {
e.printStackTrace();
} finally {
//關閉資源
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}