Java的I/O框架、網絡編程、反射

【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;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章