30天搞定Java--day27

每日一考和複習

每日一考

  1. 說明流的三種分類方式
1.流向:輸入流、輸出流
2.數據單位:字節流、字符流
3.流的角色:節點流、處理流
  1. 寫出4個IO流中的抽象基類,4個文件流,4個緩衝流
1.InputStream
  OutputStream
  Writer
  Reader
2.FileInputStream
  FileOutputStream
  FileWriter
  FileReader
3.BufferedInputStream
  BufferedOutputStream
  BufferedWriter
  BufferedReader
  1. 字節流與字符流的區別與使用情境
1.字節流一般用於傳輸文本文件
2.字符流一般用於傳輸文本文件
  1. 使用緩衝流實現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();
        }
    }
}
  1. 轉換流是哪兩個類,分別的作用是什麼?請分別創建兩個類的對象
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不能序列化statictransient修飾的成員變量

序列化過程:將內存中的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

  1. RandomAccessFile直接繼承於java.lang.Object類,實現了DataInput和DataOutput接口

  2. RandomAccessFile既可以作爲一個輸入流,又可以作爲一個輸出流

  3. 如果RandomAccessFile作爲輸出流時,寫出到的文件如果不存在,則在執行過程中自動創建
    如果寫出到的文件存在,則會對原有文件內容進行覆蓋。(默認情況下,從頭覆蓋,也可以設置開始的位置)

  4. 可以通過相關的操作,實現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();
        }
    }
}

網絡編程

網絡編程概述

  • 網絡編程的目的
    直接或間接地通過網絡協議與其它計算機實現數據交換,進行通訊
  • 網絡編程中有兩個主要的問題
    1. 如何準確地定位網絡上一臺或多臺主機;定位主機上的特定的應用
    2. 找到主機後如何可靠高效地進行數據傳輸

網絡通信要素概述

  • 通信雙方地址
    IP & 端口號
  • 一定的規則
    • OSI參考模型:模型過於理想化,未能在因特網上進行廣泛推廣
    • TCP/IP參考模型(或TCP/IP協議):事實上的國際標準

通信要素1:IP和端口號

  1. IP:唯一的標識 Internet 上的計算機(通信實體)

  2. 在Java中使用InetAddress類代表IP

  3. IP分類:IPv4 和 IPv6 ;萬維網 和 局域網

  4. 域名: www.baidu.com/ www.mi.com/ www.sina.com/ www.jd.com/ www.vip.com

  5. 本地迴路地址:127.0.0.1 對應着:localhost

  6. 如何實例化InetAddress:兩個方法:getByName(String host)getLocalHost()
    兩個常用方法:getHostName()/getHostAddress()

  7. 端口號:正在計算機上運行的進程
    要求:不同的進程有不同的端口號
    範圍:被規定爲一個 16 位的整數 0~65535

  8. 端口號與IP地址的組合得出一個網絡套接字:Socket

通信要素2:網絡協議

  • 網絡通信協議
    計算機網絡中實現通信必須有一些約定,即通信協議,對速率、傳輸代碼、代碼結構、傳輸控制步驟、出錯控制等制定標準
  • 通信協議分層的思想
    在制定協議時,把複雜成份分解成一些簡單的成份,再將它們復合起來。最常用的複合方式是層次方式,即同層間可以通信、上一層可以調用下一層,而與再下一層不發生關係。各層互不影響,利於系統的開發和擴展
  • 傳輸層協議中有兩個非常重要的協議
    TCP協議 和 UDP協議

TCP網絡編程

  • 客戶端Socket的工作過程包含以下四個基本的步驟

    1. 創建 Socket:根據指定服務端的 IP 地址或端口號構造 Socket 類對象。若服務器端響應,則建立客戶端到服務器的通信線路。若連接失敗,會出現異常
    2. 打開連接到 Socket 的輸入/出流: 使用 getInputStream()方法獲得輸入流,使用getOutputStream()方法獲得輸出流,進行數據傳輸
    3. 按照一定的協議對 Socket 進行讀/寫操作:通過輸入流讀取服務器放入線路的信息(但不能讀取自己放入線路的信息),通過輸出流將信息寫入線程
    4. 關閉 Socket:斷開客戶端到服務器的連接,釋放線路
  • 服務器程序的工作過程包含以下四個基本的步驟

    1. 調用ServerSocket(int port):創建一個服務器端套接字,並綁定到指定端口上。用於監聽客戶端的請求
    2. 調用 accept():監聽連接請求,如果客戶端請求連接,則接受連接,返回通信套接字對象
    3. 調用該Socket類對象的 getOutputStream()getInputStream ():獲取輸出流和輸入流,開始網絡數據的發送和接收
    4. 關閉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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章