【Java總結】-【提高篇(第七週)】 後續每週總結一次
目錄
I/O框架
什麼是流
- 內存與存儲設備之間傳輸數據的通道
流的分類
- 方向
- 輸入流 : 將存儲設備中的內容讀入到內存中
- 輸出流 : 將內存中的內容寫入到存儲設備中
- 單位
- 字節流 : 以字節爲單位,可以讀寫所有數據
- 字符流 : 以字符爲單位,只能讀寫文本數據
- 功能
- 節點流 : 具有實際傳輸數據的讀寫功能
- 過濾流 : 在節點流的基礎上增強功能
字節流
- InputStream抽象類
- OutputStream抽象類
- 字節節點流
- FileInputStream
- FileOutputStream
- 字節過濾流
- BufferedOutputStream
- BufferedInputStream
- 提供了IO效率,減少訪問磁盤的次數。數據存放在緩衝區中。flush()刷新緩衝區,提交數據
- 對象流
- ObjectInputStream
- ObjectOutputStream
- 增強讀寫8中基本數據類型和字符串功能
- 讀寫對象,可以實現對象的持久化存儲
- 序列化和反序列化
- 必須實現接口Serializable
- 必須保證所有屬性均支持序列化
- Transient修飾的爲臨時屬性,不參與序列化
- 讀取到文件末尾時:java.IO.EOFException
public class TestInputAndOutputStream {
List<String> testList = new ArrayList<String>();
static String path = "./src/txt/a.txt";
public static void main(String[] args) {
//testFileOutPut();
//testFileInput();
//testBufferedInput();
//testBufferedOutput();
testObjectInputStream();
testObjectOutputStream();
}
private static void testFileInput() {
try(
// 創建一個FileInputStream對象
InputStream inputStream = new FileInputStream(path);
) {
int n = 0;
byte[] bytes = testDataLength();
while((n=inputStream.read(bytes)) != -1) {
for (int i = 0; i < n; i++) {
System.out.print((char) bytes[i]);
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testFileOutPut() {
try(OutputStream op = new FileOutputStream(path,true);) {
op.write(testData());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void testBufferedInput() {
try (BufferedInputStream is = new BufferedInputStream(new FileInputStream(path)); ){
byte[] bytes = testData();
int n=0;
while ((n=is.read(bytes))!=-1) {
for (int i = 0; i < n; i++) {
System.out.print((char)bytes[i]);
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testBufferedOutput() {
try (OutputStream is = new BufferedOutputStream(new FileOutputStream(path,true)); ){
byte[] bytes = testData();
is.write(testData());
is.flush();
} catch (Exception e) {
// TODO: handle exception
e.getMessage();
}
}
private static void testObjectInputStream() {
try(ObjectInputStream iStream = new ObjectInputStream(new FileInputStream(path));) {
byte bytes[] = testDataLength();
// 常常用來反序列化
Object stream ;
while((stream = iStream.readObject())!=null) {
testSerializable t1 = (testSerializable)stream;
System.out.println(t1.toString());
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testObjectOutputStream() {
try(ObjectOutputStream iStream = new ObjectOutputStream(new FileOutputStream(path));) {
byte bytes[] = testDataLength();
// 常常用來反序列化
iStream.writeObject(new testSerializable("李敢敢",23));
iStream.writeObject(new testSerializable("趙巖巖",23));
iStream.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
// 讀取數據的容量大小
private static byte[] testDataLength() {
return new byte[1024];
}
// 準備數據
private static byte[] testData() {
byte[] bytes = new byte[] {'1','2','3','4','5','6','7','8','8','a','b','c'};
return bytes;
}
}
class testSerializable implements Serializable{
public String name;
public Integer age;
public testSerializable(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "testSerializable [name=" + name + ", age=" + age + "]";
}
}
字符編碼
- GBK 簡體中文、擴展
- UTF-8針對Unicode的可變字符編碼
- GB2312簡體中文
- 當編碼和解碼方式不一致時,會出現亂碼
字符流
- 字符流的父類
- Reader
- Writer
- 字符節點流
- FileReader
- FileWriter
- 字符過濾流
- BufferedWriter/PrintWriter
- BufferedReader
- 支持寫一行、讀一行
public class TestReaderAndWriter {
static String path = "./src/txt/a.txt";
public static void main(String[] args) {
// ---
testFileWriter();
testFileReader();
// ---
testBufferedWriter();
testBufferedReader();
testPrintWriter();
testBufferedReader();
}
private static void testFileReader() {
try(Reader reader = new FileReader(path);) {
int n;
char[] bytes =dataLength();
while((n=reader.read(bytes))!=-1) {
for (int i = 0; i < n; i++) {
System.out.print(bytes[i]);
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testFileWriter() {
try(Writer w = new FileWriter(path);) {
w.write("I love you!");
w.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testBufferedWriter() {
try(BufferedWriter bfw = new BufferedWriter(new FileWriter(path));) {
bfw.write("基本沒啥區別");
bfw.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testBufferedReader() {
try(BufferedReader br = new BufferedReader(new FileReader(path));) {
String str;
while((str=br.readLine())!=null) {
System.out.println(str);
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static void testPrintWriter() {
try(PrintWriter pw = new PrintWriter(new FileWriter(path));) {
pw.println("牀前明月光");
pw.println("疑似地上霜");
pw.println("舉頭望明月");
pw.println("巖巖在身旁");
pw.flush();
} catch (Exception e) {
// TODO: handle exception
}
}
private static char[] dataLength() {
return new char[1024];
}
}
字符節點流
- 字符節點流
- 橋轉換流
- InputStreamReader
- OutputStreamWriter
- 可將字節流轉換爲字符流。可設置編碼方式,編碼與解碼一定要一致。
- 使用步驟
- 創建節點流
- 創建過濾流,設置字符編碼
- 封裝過濾流
- 讀寫數據
- 關閉流
- 橋轉換流
public class TestConvertStream {
public static void main(String[] args) {
String path ="./src/txt/a.txt";
try( //1.創建字節流
FileInputStream is = new FileInputStream(path);
FileOutputStream os = new FileOutputStream(path,true);
//2.創建轉換流
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
OutputStreamWriter isw = new OutputStreamWriter(os,"UTF-8");
//3.創建字符流
BufferedReader br = new BufferedReader(isr);
PrintWriter pw = new PrintWriter(isw);
){
//1.讀取
String string;
while((string = br.readLine())!=null) {
System.out.println(string);
}
//2.寫入
pw.println("牀前明月光\r\n" +
"疑似地上霜\r\n" +
"舉頭望明月\r\n" +
"巖巖在身旁\r\n" +
"");
// pw.flush();
}catch (Exception e) {
// TODO: handle exception
}
}
}
File
- FileFilter
- File類的構造方法
public class TestFile {
public static void main(String[] args) throws IOException {
File file = new File("./src");
file.canExecute();//是否可執行
file.canRead();//是否可讀
file.canWrite();//是否可寫
//file.createNewFile();// 創建一個文件
//file.mkdir();//創建文件夾
//file.mkdirs();//遞歸文件夾
//file.delete();//刪除文件或文件夾
//file.exists();//判斷文件是否存在
System.out.println(file.getAbsoluteFile());//獲得文件絕對路徑
System.out.println(file.getAbsolutePath());//獲得文件絕對路徑
System.out.println(file.getName());//獲得文件名
System.out.println(file.getParent());//獲得文件父目錄
System.out.println(file.getParentFile());//獲得文件父目錄
file.isDirectory();//判斷是否是目錄
file.isFile();//判斷是否是文件
System.out.println("---");
// 遞歸遍歷
readfile(file.listFiles());
// 遍歷一層
File[] files = file.listFiles((pathname)->{
if(pathname.isFile() && pathname.getName().endsWith(".java")) {
return true;
}
return false;
});
System.out.println("---------");
for (File file2 : files) {
System.out.println(file2);
}
}
private static void readfile(File[] files) {
if(files == null) {
return;
}
for (File file : files) {
if(file.isFile()) {
System.out.println(file.getName());
}else if(file.isDirectory()) {
readfile(file.listFiles());
}
}
}
}
網絡編程
- 由點和線構成的,標識諸多對象間的相互聯繫 ##### 計算機網絡- 實現資源共享和信息傳遞,通過通信線路連接起來的若干(Host)
- 互聯網:點與點
- 萬維網:端與端相連
- 物聯網:物與物相連
- 網絡編程:讓計算機與計算機之間建立了鏈接、進行通信
網絡模型
- 第一層:物理層(雙絞線、光導纖維)
- 第二層:鏈路層(MAC)
- 第三層:網絡層(IP地址)
- 第四層:傳輸層(TCP、UDP)
- 第五層:會話層(斷點續傳)
- 第六層:表示層(對數據轉化以及加密)
- 第七層:應用層(HTTP、FTP、SMTP)
TCP/IP模型
- 一組用於實現網絡互連的通信協議,分爲四層
- 第一層:網絡接口層(以太網、ADSL)
- 第二層:網絡層(分配地址、傳輸數據、IP地址)
- 第三層:傳輸層(文本數據,協議是Tcp、UDP協議)
- 第四層:應用層(負責傳送最終形態的數據,協議爲HTTP、FTP)
TCP/UDP
- tcp:傳輸控制協議 :是一種面向連接、可靠的、基於字節流的傳輸層通信
數據大小無限制 - 建立連接的過程需要三次握手
- 斷開連接的過程需要四次揮手
- UDP:用戶數據報協議:是一種無連接的傳輸層協議,提供面向事務的簡單、不可靠信息傳送服務
- 每個包大小是64KB
IP
- 互聯網協議/網際協議地址
- 分配給互聯網設備的唯一數字標識
- IPV4
4字節32位正數,分成4段8位的二進制數
255.255.255.255 - IPV6
16字節128位正數,分成8段十六進制正數
FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF - 迴環地址
127.0.0.1
localhost - Port(端口)
- 在通信實體上進行網絡通訊的程序的唯一標識 0~65535
- Mysql:3306 Oracle:1521 Tomcat:8080
InetAddress
- 標識互聯網協議(IP)地址對象。封裝了與該IP地址對象相關的所有信息,並提供常用方法
- 無法直接創建對象,構造方法私有化,需要通過getXXX方法獲得
public class TestInetAddress {
public static void main(String[] args) throws UnknownHostException {
//獲取本地連接
InetAddress ia = InetAddress.getLocalHost();
// 獲取本機地址
System.out.println(ia.getAddress());
// 獲取本機的ip
System.out.println(ia.getHostAddress());
//獲取本機名
System.out.println(ia.getHostName());
//獲取本機名/ip
System.out.println(ia.getLocalHost());
}
}
基於TCP的網絡編程
- Socket
- 是網絡中的一個通訊節點
- 分爲客戶端Socket 服務端ServerSocket
- 通訊要求:IP地址和端口Port
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//創建客戶端
Socket client = new Socket("127.0.0.1",9999);
//創建輸入輸出流
//創建輸入輸出流
PrintWriter pw = new PrintWriter(new OutputStreamWriter(client.getOutputStream(),"UTF-8"));
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
pw.println("牀前明月光");
pw.println("疑似地上霜");
pw.println("舉頭望明月");
pw.println("巖巖在身旁");
pw.flush();
String string;
while((string=br.readLine())!=null)
{
System.out.println(string);
}
pw.close();
br.close();
client.close();
}
}
public class Server {
public static void main(String[] args) throws IOException {
//配置服務器端口號
ServerSocket server = new ServerSocket(9999);
System.out.println("服務器啓動");
//監聽客戶端
Socket client = server.accept();
//創建輸入輸出流
PrintWriter pw = new PrintWriter(new OutputStreamWriter(client.getOutputStream(),"UTF-8"));
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
// 響應
pw.println("歡迎"+client.getInetAddress().getHostName()+"訪問客戶端");
pw.flush();
String string;
while((string=br.readLine())!=null)
{
System.out.println(string);
}
//----------------
pw.close();
br.close();
client.close();
server.close();
}
}
反射
類的對象
- 基於某個類new出來的對象,也稱爲實例對象public class TestA{
public static void main(String[] args){
TestA t = new TestA(); //t就是實例對象
}
}
類對象
- 類加載的產物
- 封裝了一個類所有信息(類名、父類、接口、屬性、方法、構造方法)
- 一個.class文件就代表一個類對象
獲取類對象
- 通過類的對象,回去類對象
Student s = new Student();
Class c = s.getClass();
- 通過類名獲取類對象
Class c = 類名.class
- 通過靜態方法獲取類對象
Class.forName("包名.類名")
常用方法
public String getName()//獲取全路徑類名
public Package getPackage();//獲取全路徑包名
public Class<? super T> getSuperclass();//獲取父類返回Class
public Class<?>[] getInterfaces() // 獲取接口返回數組
public Field[] getFields()//獲取屬性(自身加父類的公開屬性) 必須是Public的
public Field[] getDeclaredFields()//獲取自身所有屬性不分權限
public Method[] getMethods()// 獲取方法(自身的和父類的公共方法)必須是Public的
public Method[] getDeclaredMethods()//獲取自身所有非構造方法
getReturnType() 方法返回值類型
public Constructor<?>[] getConstructors()
public Constructor<?>[] getDeclaredConstructors()
public T newInstance()
package com.review.reflect;
public class TestReflects {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//方法一
Student t = new Student();
Class c1 = t.getClass();
//方法二
Class c2 = Student.class;
//方法三
Class c3 = Class.forName("com.review.reflect.Student");
// 獲取全路徑類名
String name = c2.getName();
// 獲取全路徑報名
Package p = c2.getPackage();
//獲取父類返回Class
Class cparent = c2.getSuperclass();
// 獲取接口返回數組
Class[] ci = c2.getInterfaces();
//獲取屬性(自身加父類的公開屬性) 必須是Public的
c2.getFields();
//獲取自身所有屬性不分權限
c2.getDeclaredFields();
// 獲取方法(自身的和父類的公共方法)必須是Public的
c2.getMethods();
//獲取自身所有非構造方法
c2.getDeclaredMethods();
// 獲取構造函數
c2.getConstructors();
c2.getDeclaredConstructors();
// 實例化
Student student = (Student)c2.newInstance();
}
}
class Student{
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student [name=" + name + ", sex=" + sex + "]";
}
public Student(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
}
工廠設計模式
- 開發中有一個非常重要的原則,:“開閉原則”.對拓展開放、對修改關閉
- 工廠模式主要負責對象創建的問題
- 通過反射進行工廠模式的設計,完成動態的對象創建
public class TestFactory {
public static void main(String[] args) {
Object o = createObject("com.qfedu.review.reflect.Person");
Class c= o.getClass();
System.out.println(o.getClass().getTypeName());
}
private static Object createObject(String className) {
try{
Class sClass = Class.forName(className);
return sClass.newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//使用反射技術執行任何方法
public static void invokeAny(Object obj,String methodName,Class[] types,Object...args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//類對象
Class c = obj.getClass();
//獲得方法的對象Method
Method m = c.getDeclaredMethod(methodName, types);
//執行方法
m.invoke(c,args);
}
}
class Person{
}
單例模式
- 只允許創建一個該類的對象
- 方式1:餓漢式(類加載時創建,天生線程安全)
- 方式2:懶漢式(使用時創建,線程不安全,需要加鎖)
- 方式3:懶漢式(使用時創建、線程安全,天生不需要加鎖)
public class TestSingleton {
public static void main(String[] args) {
}
// 方式1
}
// 餓漢
class TestSingletonOne {
private final static TestSingletonOne tobj = new TestSingletonOne();
private TestSingletonOne() {}
public TestSingletonOne CreateObj() {
return tobj;
}
}
// 懶漢1
class TestSingletonTwo {
private static TestSingletonTwo tobj = null;
private TestSingletonTwo() {}
synchronized public TestSingletonTwo CreateObj() {
if(this.tobj == null) {
this.tobj = new TestSingletonTwo();
}
return tobj;
}
}
// 懶漢2
class TestSingletonThree {
private TestSingletonThree() {}
private static class Create{
final static TestSingletonThree tobj =new TestSingletonThree();
}
public TestSingletonThree CreateObj() {
return Create.tobj;
}
}