Skip to content

Latest commit

 

History

History
558 lines (474 loc) · 13.6 KB

Java中的IO流和反射.md

File metadata and controls

558 lines (474 loc) · 13.6 KB

一、定义

流是指一连串流动的字符,是以先进先出的方式发送信息的通道。程序和数据之间是通过流进行关联的。

二、分类

1、按流向分 输出流:OutputStream和Writer作为基类 输入流:InputStream和Reader作为基类 2、按处理数据的单元划分 字节流:nputStream/OutputStream作为基类 字符流:Reader/Writer作为基类

三、流之间的层级关系

上层为基类 1、输入 Reader InputStreamReader(可设置字符编码) Bufferendreader(带有缓冲区) InputStream FileInputStream objecInputStream(反序列化) DateInputStream(读二进制文件) 2、输出 Writer OuputStreamWriterr(可设置字符编码) BufferendWriterr(带有缓冲区) InputStream FileOutputStream objecOutputStream(序列化) DateIOutputStream(读二进制文件)

四、流的正确使用

1、File类操作文件

package demo1;

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

/*
 * 使用File类创建文件,并实现更删除、显示文件名和路径操作
 */
public class Test1 {
	public static void main(String[] args) throws IOException {
		File file = new File("D:\\test1.txt");
		if(!file.exists()) {
			file.createNewFile();//不存在创建
		}else {
			file.delete();//存在删除
		}
		System.out.println("该文件的绝对路径名为"+file.getAbsolutePath());
		System.out.println("该文件名为:"+file.getName());
	}
}

特别注意:创建File对象的时候可以放决相对路径也可以放决对路径 直接写test.txt代表的是在该项目底下的文件 而如果携程D:\test.txt的话是代表此文件 在D盘下的文件

File类常用方法:

方法 说明
boolean exisit() 判断文件是否存在
String getName() 获得文件名
boolean creatNewFile() 创建文件(创建前要判断文件是否存在 )

2、使用字节流FileInputStream读文本文件

package demo2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

/*
 * 字节流FileInputStream读取文件
 */
public class Test1 {
	public static void main(String[] args) throws Exception {
		File file =new File("demo2.txt");
		FileInputStream fis = new FileInputStream(file);
		byte[] b = new byte[fis.available()];
		int data=-1;
		while((data=fis.read(b))!=-1) {
		}
		String str = new String(b);//将字节数组变为字符串
		System.out.println(str);
		
		fis.close();
	}
}

FileInputStream 常用方法

方法 说明
inr read((byte[] b) 将数据缓存在字节数组中最后通过String的构造方法将字节数组转换成字符串输出
int read() 一个字节一个字节的读
3、使用字节流FileInputStream和FileOutputStream复制文本文件
package demo2;

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

/*
 * 复制文件
 */
public class Test2 {
	public static void main(String[] args) {
		FileInputStream fis =null;
		
		FileOutputStream fos=null;
		
		try {
			fis= new FileInputStream("D:\\demo1.txt");
			byte[] b = new byte[fis.available()];
			int date =-1;
			while((date=fis.read(b))!=-1){
			}
			
			fos = new FileOutputStream("E:\\Java\\java学习\\代码\\demo1.txt");
			fos.write(b);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(null!=fos){
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(null!=fis){
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

4、使用DataInputStream和DataOutputStream读写二进制文件

package demo3;

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

/*
 * 复制图片,二进制流的应用
 */
public class Test1 {
	public static void main(String[] args) throws Exception {
		DataInputStream dis = new DataInputStream(new FileInputStream("D:\\1.jpg"));
		DataOutputStream  dos =new DataOutputStream(new FileOutputStream("E:\\Java\\java学习\\代码\\t.jpg"));
		
		int date=-1;
		while((date=dis.read())!=-1){
			dos.write(date);
		}
		
		dos.close();
		dis.close();
	}
}

5、字符流FileReader & FileWriter

package demo4;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;

/*
 * 字符流FileReader & FileWriter
 */
public class Test1 {
	public static void main(String[] args) throws Exception {
		FileReader fr = new FileReader("demo2.txt");
		//方式一、一个字符一个字符的读
//		int date=-1;
//		while((date=fr.read())!=-1) {
//			System.out.print((char)date);
//		}
		
		//方式二:字符数组读文件
		char[] c = new char[1024];
		int data =-1;
		while((data=fr.read(c))!=-1) {
			
		}
		System.out.println(c);
		
		//为读出的文本文件追加字符
		FileWriter fw = new FileWriter("demo2.txt",true);
		fw.write("我做主");
		
		//关闭流
		fw.close();
		fr.close();
	}
}

6、使用带有缓冲区的流输入输出,异常处理

package demo5;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

/*
 * 使用带有缓冲区的流输入输出,异常处理
 */
public class Test1 {
	public static void main(String[] args) {

		InputStream is = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		BufferedWriter bw = null;

		try {
			// 读取文件
			is = new FileInputStream("demo5.txt");
			isr = new InputStreamReader(is, "GBK");
			br = new BufferedReader(isr);
			String info = null;
			while ((info = br.readLine()) != null) {
				System.out.println(info);
			}
			// 写入新的文本
			bw = new BufferedWriter(new FileWriter("demo5.txt", true));//熟悉之后都可以采用这种方式进行简写
			bw.newLine();
			bw.write("今天也要元气满满哦!");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {//注意如果不管流的话会导致很多东西出现bug,如果有bug先找是否正确的关闭流了
			if (null != bw) {
				try {
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != br) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != isr) {
				try {
					isr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != is) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}
}

注意指定字符编码,请确认是GBK还是UTF-8

五、一个重要综合性利用流的例子

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

public class IoDemo1 {
	public static void main(String[] args) {
		InputStream is = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		OutputStream os = null;
		OutputStreamWriter osw = null;
		BufferedWriter bw = null;
		try {
			// 读
			is = new FileInputStream("t1.txt");
			isr = new InputStreamReader(is, "GBK");
			br = new BufferedReader(isr);
			String info = br.readLine();
			System.out.println(info);
			// 写
			os = new FileOutputStream("t2.txt",true);
			osw = new OutputStreamWriter(os, "GBK");
			bw = new BufferedWriter(osw);
			bw.newLine();
			bw.write(info);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				bw.close();
				osw.close();
				os.close();
				br.close();
				isr.close();
				is.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}

特别注意:一定要关闭流,有时候没关闭会出现很多的错误

六、序列化和反序列化

1、使用序列化保存对象信息(写出 objecOutputStream)

2、使用反序列化获取对象信息(写出 objecInputStream) 3、例子:

package Demo1;

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

/*
 * 序列化和反序列化
 */
public class Test1 {
	public static void main(String[] args) throws Exception, IOException {
		ArrayList<Student> list = new ArrayList<Student>();
		Student stu1 =new Student("jck",12,"男");
		Student stu2 =new Student("lick",13,"男");
		Student stu3 =new Student("as",12,"女");
		
		list.add(stu1);
		list.add(stu2);
		list.add(stu3);
		//反序列化储存
		
		ObjectOutputStream oos =new ObjectOutputStream(new FileOutputStream("demo1.txt"));
		oos.writeObject(list);
		
		//反序列化
		ObjectInputStream ois =new ObjectInputStream(new FileInputStream("demo1.txt"));
		Object obj=ois.readObject();
		ArrayList<Student> stuList = (ArrayList<Student> )obj;
		for(int i =0;i<stuList.size();i++) {
			Student stu=stuList.get(i);
			System.out.println(stu);
		}
		
		
	}
}

七、反射

package Demo2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test1 {
	public static void main(String[] args) {
		//先获取Student类对应的Class对象
		Class cla=Student.class;
		
		//获取所有构造方法
		Constructor[] cons=cla.getConstructors();
		
		//获取所有构造方法的个数
		System.out.println(cons.length);
		
		//获取所有构造方法名字
		for (int i = 0; i < cons.length; i++) {
			System.out.println(cons[i].getName());
		}
		
		//获取共有的属性(只能是public修饰的)
		Field[] fields=cla.getFields();
		for (int i = 0; i < fields.length; i++) {
			System.out.println(fields[i].getName());
		}
		//获取所有的属性
		Field[] fis=cla.getDeclaredFields();
		for (int i = 0;  i< fis.length; i++) {
			System.out.println(fis[i].getType());
		}
		
		//获取类的方法
		Method[] methods=cla.getMethods();
		for (int i = 0; i < methods.length; i++) {
			System.out.println(methods[i].getName());
		}
	}
}
package Demo2;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 通过反射使用有参构造方法构造Student对象
 * @author Administrator
 *
 */
public class Test2 {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		//获取Student对应的Class对象
		Class<Student> cla=Student.class;
		//获取Class对象中的构造方法
		Constructor<Student> cons=cla.getConstructor(String.class,int.class,String.class);
		//为构造方法传递参数
		Student stu=cons.newInstance("jack",100,"123456");
		System.out.println(stu);
	}
}
package Demo2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/*
 * 通过反射使用有参构造方法构造Student对象
 */
public class Test3 {
	public static void main(String[] args) throws Exception, SecurityException {
		//获取Student的class对象
		Class cla = Student.class;
		//获取Class对象中的构造方法
		Constructor<Student> cons=cla.getConstructor();
		Student stu=cons.newInstance();
		//获得指定set方法为属性赋值
		Method setNameMethod=cla.getDeclaredMethod("setName", String.class);
		setNameMethod.invoke(stu, "jack");
		Method setAgeMethod=cla.getDeclaredMethod("setAge", int.class);
		setAgeMethod.invoke(stu, 18);
		Method setSexMethod=cla.getDeclaredMethod("setSex", String.class);
		setSexMethod.invoke(stu, "男");
		
		
		
		System.out.println(stu);
	}
}
package Demo2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/*
 *通过反射直接为私有属性赋值 
 */
public class Test4 {
	public static void main(String[] args) throws Exception, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// 获取Student的class对象
		Class cla = Student.class;
		// 获取Class对象中的构造方法
		Constructor<Student> cons = cla.getConstructor();
		Student stu = cons.newInstance();
		
		//访问私有成员
		Field nameField=cla.getDeclaredField("name");
		//获取私有属性的操作权限
		nameField.setAccessible(true);
		nameField.set(stu, "张三");
		
		Field ageField=cla.getDeclaredField("age");
		//获取私有属性的操作权限
		ageField.setAccessible(true);
		ageField.set(stu, 30);
		Field sexField=cla.getDeclaredField("sex");
		//获取私有属性的操作权限
		sexField.setAccessible(true);
		sexField.set(stu, "男");
		
		
		System.out.println(stu);
	}
}

反射机制在java框架中会用到! 掌握流的类名,通过相关的构造方法去构造流!