文件输入和输出---字符流

在这里插入图片描述

1. 使用字符流来读写文本文件

**字符流:**可以处理能用Notepad++打开不乱码的文件。


字符输入流Reader -> InputStreamReader -> FileReader

构造:

​ FileReader(File file);

​ FileReader(String path);

​ InputStreamReader(InputStream is);

​ InputStreamReader(InputStream is,String charsetName); 可以指定字符集(字符编码)名称

关于字符编码/字符集的补充:

​ 举例:当你用Notepad++存储一段内容时,到底在干什么?

​ 当你输入了内容之后,它默认会以UTF-8进行解码,然后再通过UTF-8进行编码用于显示给你。

​ 解码和编码的字符集必须保持一致,否则会出现乱码。

FileReader常用方法:

​ int read(char[] cha); 读取字符数据 将 数据读取到字符数组中 返回字符数

在这里插入图片描述


读取a.txt里面的内容(前提a.txt必须存在)

FileReader filereader=null;
		try {
			//1 创建对象 如果找不到a.txt会报错
			 filereader=new FileReader("d:\\a.txt");
			//2 使用api读取信息
			 char[] chars=new char[1024];
			 // 将字符读取到字符数组中  并且返回读取字符数
			// 文本文件(通过指定的字符集进行了编码显示的效果)  ->  通过字节流读取  ->  以指定的字符集再进行编码
			
			 filereader.read(chars);
			 String str = new String(chars);
			 //写成1024是个习惯性问题 但是其实我们没有那么多字符 最后会有很多空格 所以需要去掉空格
			 System.out.println(str.trim());
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				filereader.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

在这里插入图片描述
此时控制台输出黑色倔犟


字符输出流Writer -> OutputStreamWriter -> FileWriter

构造:

​ FileWriter(File file);

​ FileWriter(String path);

​ OutputStreamWriter(OutputStream os);

​ OutputStreamWriter(OutputStream os,String chasetName); 可以将字节流转换为字符流

常用方法:

​ write(String str);

​ write(String str,int offset,int length);

​ write(char[] cha, int offset,int length);


把内容输出到a.txt中 这个a.txt不一定非要存在

FileWriter fw=null;
		try {
			//创建文件 只指定输出目的地
			 fw=new FileWriter("d:\\a.txt");
			// fw.write("黑色heise");
			
			 //输出指定字符串   黑色
			 fw.write("黑色heise",0,2);
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

进行一个文件的复制

FileReader fr=null;
		FileWriter fw=null;
		try {
			//指定数据源
			fr=new FileReader("d:\\a.txt");
			//指定输出目的地
			fw=new FileWriter("f:\\a.txt");
			
			//字符输入流读取数据[边读边写]
			char[] chars=new char[1024];
			int len=0;
			
			while((len=fr.read(chars))!=-1) {
				// 4.字符输出流输出数据
				fw.write(chars,0,len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//关流
			try {
				fw.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

字节流:

​ 字节输入流:InputStream -> FileInputStream

​ 字节输出流:OutputStream -> FileOutputStream

2. 会使用高效缓冲流读写文本文件

高效缓冲字符流

输入流:BufferedReader

构造:

​ BufferedReader(Reader reader);

常用方法:

​ String readLine(); 读取一行

// 1.创建对象  最后一个可以不加分号
		try(FileReader fr = new FileReader("d:/a.txt");
			BufferedReader br = new BufferedReader(fr)){
			
			// 2.读取一行
			/*String readLine = br.readLine();
			System.out.println(readLine);*/
			
			String str = null;
			while((str = br.readLine()) != null) {
				System.out.println(str);
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}

​ -------------------------------------------------------------------

输出流:BufferedWriter

构造:

​ BufferedWriter(Writer writer);

常用方法:

​ write(String str);

​ writer(String str,int offset,int length);

​ write(char[] cha, int offset,int length);

​ 因为有缓冲区,所以如果需要立即将内容输出到文本,需要调用flush()方法刷新缓冲区。

​ 关流也会刷新缓冲区。

FileWriter fw = null;
		BufferedWriter bw = null;
		try {
			// 1.指定输出目的地
			fw = new FileWriter("e:/a.txt");
			bw = new BufferedWriter(fw);
			
			// 2.和普通字符流方法相同
			bw.write("haha");
			// 刷新缓冲区 将内容输出  不再等待缓冲区满
			bw.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				bw.close();
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

FileReader fr = null;
		BufferedReader br = null;
		FileWriter fw = null;
		BufferedWriter bw = null;
		try {
			fr = new FileReader("d:\\a.txt");
			br = new BufferedReader(fr);
			// 2.指定输出目的地
			fw = new FileWriter("e:/pet.txt");
			bw = new BufferedWriter(fw);

			StringBuffer sb = new StringBuffer();
			String str = null;
			while ((str = br.readLine()) != null) {
				sb.append(str);
			}
			System.out.println(sb);
			String temStr = sb.toString();
//			temStr = temStr.replace("{name}", "花花");
//			temStr=temStr.replace("{type}", "阿拉斯加");
//			temStr=temStr.replace("{master}", "黑色");
			String afterStr = temStr.replace("{name}", "花花").replace("{type}", "阿拉斯加").replace("{master}", "黑色");

			fw.write(afterStr);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {// 6.关流
			try {
				bw.close();
				fw.close();
				br.close();
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

a.txt里面的内容:您好 我的名字是{name},我是一只{type},我的主人是{master}

3. 使用对象流实现序列化和反序列化

在这里插入图片描述

serializable

一个合格的JavaBean类应该有以下组成:

  1. 属性私有化
  2. 提供公共的getter/setter方法
  3. 提供无参构造
  4. 实现序列化接口

当Java在进行对象的序列化(对象一定实现过序列化接口)时,它会自动生成一个序列化版本ID(serialVersionUID),同理,在读取对象时(反序列化)时,Java还会再生成一个序列化版本ID。

java.io.InvalidClassException: cn.kgc.demo4.User; local class incompatible: stream classdesc serialVersionUID = -5990646266163102806, local class serialVersionUID = -3392451066535050577
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1883)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1749)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2040)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1571)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
	at cn.kgc.demo4.Demo2.main(Demo2.java:19)


序列化

/**
 * 输出对象   序列化:将内存中的Java对象以指定的二进制序列写入特定的流(二进制序列)
 * 
 * 2019年3月3日 上午11:08:20
 */
public class Demo1 {

	public static void main(String[] args) {
		
		try (OutputStream os = new FileOutputStream("d:/object.txt");
				ObjectOutputStream oos = new ObjectOutputStream(os);){
			
			User user = new User();
			user.setName("xxx");
			user.setAge(12);
			// 序列化
			oos.writeObject(user);
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

输出的是二进制 我们看不懂
在这里插入图片描述


反序列化

/**
 * 读取对象:反序列化:将特定流中的数据重构为Java对象
 * 2019年3月3日 上午11:11:41
 */
public class Demo2 {

	public static void main(String[] args) {

		try (FileInputStream fis = new FileInputStream("d:/object.txt");
				ObjectInputStream ois = new ObjectInputStream(fis)){
			
			// 反序列化
			User user = (User) ois.readObject();
			System.out.println(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}
/**
 * 用户实体
 * 2019年3月3日 上午11:07:29
 */
public class User implements Serializable {
	
	/**
	 * 序列化ID
	 */
	private static final long serialVersionUID = 1L;
	
	private String name;
	private int age;
	
	public User(){}
	// 省略getter/setter
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值