耳熟能详的Java反射和IO流,你还记得多少,真的学会了能应对面试吗???

反射

1. 概念

官方解释:反射是指在程序运行过程中,动态的获取类的信息,并且访问

我们通过反射还是获取类的信息(属性,方法,构造方法),然后访问,只不过我们现在不再以new的方式获取

Java中反射相关的API都位于java.lang.reflect包下

万物皆对象

Class 类

Method 方法

Field 属性

Constructor 构造方法

2. 使用反射获取属性

2.1 获取public修饰的属性

getFields() 获取所有的public修饰的属性对象

getField(String name) 根据名字获取单个属性对象

2.2 获取已声明的属性

getDeclaredFields()获取所有已经定义的属性对象,包括private,默认修饰符,protected,public

getDeclaredField(String name)根据名字获取单个属性对象,可以是任意访问修饰符

3. 使用反射获取方法

3.1 获取public修饰的和继承父类的方法

getMethods()获取所有public修饰的方法和继承父类的方法

getMethod()获取单个的方法

3.2获取本类定义的方法

getDeclaredMethod(String name,Class<?>.....parameterTypes>获取单个本类中声明的方法,如果访问权限不足,可以使用setAccessable(true)修改权限

getDeclaredMethods()获取所有本类中已定义的方法

4.使用反射获取构造器

4.1获取所有public修饰的构造器

getConStructors()获取public修饰的所有构造方法

getConstructor(Class.....type)获取单个的构造器对象

4.2 获取本类中定义的构造方法

getDeclaredConstructors()获取本类中定义的所有构造方法

getDeclaredConstructor()获取单个的构造方法

IO流

1.File类

File 类提供了一些用于查看文件信息的方法

package com.qfedu.test4;

import java.io.File;
import java.io.IOException;

/**
 * 	java.io.File类
 * 	此类提供了一些用于获取文件信息的方法
 * 	比如 名称  大小 等等  
 * @author WHD
 *
 */
public class TestFile {
	public static void main(String[] args) throws IOException {
		File file = new File("a.txt");
		file.createNewFile(); // 创建一个新文件
		System.out.println("文件名" + file.getName());
		System.out.println("相对路径" + file.getPath());
		System.out.println("绝对路径" + file.getAbsolutePath());
		System.out.println("是否存在" + file.exists());
		System.out.println("是否是一个文件" + file.isFile());
		System.out.println("是否是一个文件夹" + file.isDirectory());
		System.out.println("文件大小" + file.length());
		System.out.println("删除文件" + file.delete());
		
		File dir = new File("A");
		dir.mkdir();
		System.out.println("是否是一个文件夹" + dir.isDirectory());
		
		
		File dir1 = new File("E/F/G");
		dir1.mkdirs();
		
		File f = new File("C:\\Users\\WHD\\Desktop\\2103.txt");
		f.createNewFile();
		
		
	}
}

2.字节流

2.1 InputStream

字节流读取类父类,是一个抽象类,提供了各种read方法

2.1.1 FileInputStream

提供了用于读写字节的方法,可以一次读取一个字节,也可以读取一个字节数组

package com.qfedu.test5;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 	InputStream
 * 	FileInputStream 字节读取(输入流)流类
 * 		read() 每次读取一个字节 返回值为读取的内容的ascii码值
 * 		
 * 		close() 关闭资源
 * 		available() 获取当前文件可读字节数  
 * 
 * 	构造方法
 * 		FileInputStream(File file)
 *		FileInputStream(String name)	
 * @author WHD
 *
 */
public class TestFileInputStream1 {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("a.txt");
		int data = -1;
		while((data = fis.read()) != -1) {
			System.out.println((char)data);
		}
		
		fis.close(); // 关闭资源
		
		
	}
}
package com.qfedu.test5;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 	使用字节流每次读取一个byte数组
 * 	read(byte [] datas) 每次读取指定长度的字节	返回值为读取的长度 读取的内容在byte数组
 * @author WHD
 *
 */
public class TestFileInputStream2 {
	public static void main(String[] args) {
		FileInputStream  fis = null;
		try {
			fis = new FileInputStream("b.txt");
			System.out.println(fis.available());
			byte [] datas = new byte[fis.available()];
			int dataCount = -1;
			while((dataCount = fis.read(datas)) != -1) {
//				System.out.println(dataCount);
				System.out.println(new String(datas, 0, dataCount));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}	
}

2.2 OutputStream

字节写入流父类,抽象类,提供了各种wirte方法

2.2.1 FileOutputStream

字节写入流类,可以一次写入一个字节,也可以一次写入一个字节数组

package com.qfedu.test6;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 	OutputStream 父类 抽象类
 * 	FileOutputStream 
 * 	write(int chars);
 * 	write(byte [] datas);
 * 	close();
 * 	flush(); 将内存中的内容 刷新到硬盘中 字节流是直接操作硬盘的 
 * @author WHD
 *
 */
public class TestFileOutputStream {
	public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("c.txt", true); // 第二个参数为是否追加 默认为false
		fos.write(98);
		fos.close();
	}
}
package com.qfedu.test6;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 	每次写入一个字节数组
 * @author WHD
 *
 */
public class TestFileOutputStream2 {
	public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("d.txt", true);
		String info = "hello world 世界你好";
		fos.write(info.getBytes());
		fos.write("你好".getBytes());
		fos.close();
	}
}

3.字符流

3.1 Reader

字符读取流父类,抽象类。提供了各种read方法。

3.1.1 InputStreamReader

此类提供各种read方法,可以一次读取一个字符,也可以一次读取一个char数组,还支持指定读取的编码格式

package com.qfedu.test1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 	Reader类抽象类父类
 * 	InputStreamReader子类
 * 	字符读取流:
 * 	read 每次读取一个字符 返回值为读取的内容
 * 	read(char [] datas) 每次读取一个字符数组  返回值是读取的长度 内容在char数组
 * 	
 * 	close 关闭资源
 * @author WHD
 *
 */
public class TestInputStreamReader1 {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("a.txt");
		InputStreamReader isr = new InputStreamReader(fis);
		int data = -1;
		
		while((data = isr.read()) != -1){
			System.out.println((char)data);
		}
		
		
		// 关闭的顺序 先用后关
		isr.close();
		fis.close();
		
	}
}
package com.qfedu.test1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 	每次读取一个字符数组
 * @author WHD
 *
 */
public class TestInputStreamReader2 {
	public static void main(String[] args) throws IOException {
		InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
		char [] chars = new char[5];
		int readCount = 0;
		while((readCount = isr.read(chars)) != -1) {
//			System.out.println(readCount);
			System.out.println(chars);
			System.out.println(new String(chars, 0, readCount));
			System.out.println("========================");	
		}
		// 关闭资源
		isr.close();	
	}
}
package com.qfedu.test1;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 	使用InputStreamReader构造方法指定编码格式 解决乱码问题
 * 
 * 	乱码产生的原因:
 * 		编码和解码方式不统一 将会产生乱码
 * 	解决方案:
 * 		让编码和解码使用一种编码格式就可以了
 * 	
 * 	UTF-8 Unicode编码格式 万国码 支持中文及其他国家的语言
 * 	GBK 国标扩展板 支持大部分的中文简体和繁体
 * 	GB2312 国标2312 支持大部分的中文简体
 * 	ISO-8859-1 最原始的编码格式  用于处理字符串内容乱码
 * 	ANSI在不同的操作系统表示不同的编码格式  在中文Win10 表示 GBK
 * @author WHD
 *
 */
public class TestInputStreamReader3 {
	public static void main(String[] args) throws IOException {
		System.getProperties().list(System.out);
		
		
		InputStreamReader isr = new InputStreamReader(new FileInputStream("C:\\Users\\WHD\\Desktop\\2103.txt"),"utf-8");
		int data = -1;
		while(( data = isr.read()) != -1) {
			System.out.println((char)data);
		}
		
		// 关闭资源
		isr.close();
		
	}
}
3.1.1.1 FileReader

FileReader 此类只能按照本地平台默认的编码格式来读取 不能指定编码

package com.qfedu.test2;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * 	Reader
 * 	InputStreamReader
 * 	FileReader 此类只能按照本地平台默认的编码格式来读取 不能指定编码
 * 	
 * @author WHD
 *
 */
public class TestFileReader {
	public static void main(String[] args) throws IOException {
		FileReader reader = new FileReader("a.txt");
		int data = -1;
		while((data = reader.read() )!= -1){
			System.out.println((char)data);
		}
		reader.close();
	}
}
package com.qfedu.test2;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
 * 	使用FileReader每次读取一个字符数组
 * @author WHD
 *
 */
public class TestFileReader2 {
	public static void main(String[] args) throws IOException {
		FileReader reader = new FileReader("a.txt");
		char [] chs = new char[5];
		int dataCount = -1;
		while((dataCount = reader.read(chs)) != -1) {
			System.out.println(new String(chs,0,dataCount));
		}
		
		reader.close();
		
	}
}
3.1.2 BufferedReader

带有缓冲区的字符读取流,提供了独有的读取整行的方法readLine()

package com.qfedu.test2;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestBufferedReader {
	public static void main(String[] args) throws IOException {
		BufferedReader  br = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
		String line = null;
		while((line = br.readLine()) != null) {
			System.out.println(line);
		}
		// 关闭资源
		br.close();
	}
}

3.2 Writer

字符写入流父类,抽象类,提供了各种write方法

3.2.1 OutputStreamWriter

字符写入流,可以一次写入一个字符,也可以一次写入一个char数组,可以指定写入的编码格式

package com.qfedu.test3;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * 	Writer抽象类父类
 * 	OutputStreamWriter 子类
 * 	write(String str);
 * 
 * 	OutputStreamWriter 可以指定写入的编码格式
 * @author WHD
 *
 */
public class TestOutputStreamWriter {
	public static void main(String[] args) throws IOException {
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt",true));
		osw.write(98);
		osw.write("hello world");
		osw.write("世界你好".toCharArray());
		osw.flush(); // 字符流相当于有一个缓冲区 不是直接操作硬盘的
		osw.close();
	}
}
package com.qfedu.test3;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * 	Writer抽象类父类
 * 	OutputStreamWriter 子类
 * 	write(String str);
 * 
 * 	OutputStreamWriter 可以指定写入的编码格式
 * @author WHD
 *
 */
public class TestOutputStreamWriter2 {
	public static void main(String[] args) throws IOException {
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt",true),"gbk");
		osw.write(98);
		osw.write("hello world");
		osw.write("世界你好".toCharArray());
		osw.flush(); // 字符流相当于有一个缓冲区 不是直接操作硬盘的
		osw.close();
	}
}
3.2.1.1 FileWriter

FileWriter不能指定编码格式写入

package com.qfedu.test3;

import java.io.FileWriter;
import java.io.IOException;

/**
 * 	Writer
 * 	OutputStreamWriter
 * 	FileWriter不能指定编码格式写入
 * @author WHD
 *
 */
public class TestFileWriter {
	public static void main(String[] args) throws IOException {
		FileWriter fw = new FileWriter("d.txt", true); 
		fw.write("hello world");
		fw.flush();
		fw.close();
	}
}
3.2.2 BufferedWriter

此类提供的有换行的方法  newLine()

package com.qfedu.test3;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
* 	Writer
* 	BufferedWriter 
* 	此类提供的有换行的方法  newLine()
* @author WHD
*
*/
public class TestBufferedWriter {
   public static void main(String[] args) throws IOException {
   	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("e.txt")));
   	bw.write("hello world1\n");
   	bw.write("hello world2\n");
   	bw.newLine();
   	bw.write("世界你好");
   	bw.flush();
   }
}

4.数据流

4.1 DataInputStream读取二进制文件

4.2 DataOutputStream写入二进制文件

读  DataInputStream

写  DataOutputStream

package com.qfedu.test4;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 	读取二进制文件
 * 	读  DataInputStream
 * 	写  DataOutputStream
 * @author WHD
 *
 */
public class TestDataStream {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("C:\\Users\\WHD\\Desktop\\zs.jpg");
		DataInputStream dis = new DataInputStream(fis);
		byte [] datas = new byte[fis.available()];
		System.out.println(dis.read(datas));
		// System.out.println(new String(datas,0,datas.length)); 因为图片是二进制文件 所以不要打印
		
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("copyzs.jpg"));
		dos.write(datas);
		
		// 关闭资源 
		
		dos.close();
		dis.close();
		fis.close();
	
	}
}

5.对象流

5.1 序列化和反序列化

序列化:将对象写入到二进制文件中
反序列化:将存有对象的二进制文件读取为对象
注意:可以被序列化的对象所属的类必须实现Serializable接口,此接口是一个空接口,仅仅作为一个标识,表示此接口的实现类可以被序列化。
被transient修饰的属性不能被序列化。

序列化ID
用于判断读取出来的对象 是所属于哪个类的实例  相当于一个唯一表示
可以自动生成默认的1L
也可以随机生成
也可以不写  因为JVM会自动帮我们添加一个

package com.qfedu.test5;

import java.io.Serializable;
/**
 * 	Serializable接口没有方法 只相当于一个标识 标识此类的实现类可以被序列化
 * 	序列化ID 
 *	用于判断读取出来的对象 是所属于哪个类的实例  相当于一个唯一表示
 *	可以自动生成默认的1L
 *	也可以随机生成 
 *	也可以不写  因为JVM会自动帮我们添加一个
 * @author WHD
 *
 */
public class Student implements Serializable{
	private  static final long serialVersionUID = 1656714578162247302L;
	private int age;
	private String name;
	private transient String address; // 被transient修饰的属性  不能被序列化
	
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Student() {
	}
	public Student(int age, String name) {
		this.age = age;
		this.name = name;
	}
	@Override
	public String toString() {
		return "Student [age=" + age + ", name=" + name + ", address=" + address + "]";
	}
}
package com.qfedu.test5;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 	ObjectInputStream 读取对象流
 * 	ObjectOutputStream 写入对象流
 * @author WHD
 *
 */
public class TestObjectStream {
	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("stu.txt"));
		Student zhaosi = new Student(20,"赵四");
		zhaosi.setAddress("象牙山");
		Student guangkun = new Student(20,"广坤");
		guangkun.setAddress("铁岭的");
		Student dana = new Student(20,"大拿");
		dana.setAddress("东北的");
		oos.writeObject(zhaosi);
		oos.writeObject(guangkun);
		oos.writeObject(dana);
		oos.flush();
		
		
		FileInputStream fis = new FileInputStream("stu.txt");
		ObjectInputStream ois = new ObjectInputStream(fis);
		
		while(fis.available() > 0) {
			Object obj1 = ois.readObject();
			if(obj1 instanceof Student) {
				Student s = (Student) obj1;
				System.out.println(s);
			}
		}
		
		
		
//		Object obj1 = ois.readObject();
//		if(obj1 instanceof Student) {
//			Student s = (Student) obj1;
//			System.out.println(s);
//		}
//		
//		
//		Object obj2 = ois.readObject();
//		if(obj2 instanceof Student) {
//			Student s = (Student) obj2;
//			System.out.println(s);
//		}
//		
//		Object obj3 = ois.readObject();
//		if(obj3 instanceof Student) {
//			Student s = (Student) obj3;
//			System.out.println(s);
//		}
//		
		ois.close();
		oos.close();		
	}
}

NIO
NIO是一种非阻塞的、面向缓存的IO流
I0和NIO的区别
(1)IO是面向流的阻塞I0流,NIO是面向缓存的非阻塞IO流
(2)IO的通道是单向的,NIO的管道是双向的
(3)I0流在输入输出数据的时候,在输入输出数据不可用或者没有时候会把线程挂起,发生阻塞,NIO在输入输出数据的时候,是在输入输出的时候还可以执行其他操作,不会等待,所以不会发生阻塞

posted @ 2022-08-10 19:00  一眼万年的星空  阅读(41)  评论(0编辑  收藏  举报