Day21 I/O框架

Day21 I/O框架

第一节:流的概念

内存与存储设备之间传输数据的通道

数据需要借助流来传输

1.1流的分类

按方向(重点)
输入流:将<存储设备>中的内容读入到<内存>中
输出流:将<内存>中的内容写入到<存储设备>中。

按单位:
字节流:以字节为单位,可以读写所有数据 。

字符流:以字符为单位,只能读写文本数据 。


按功能:
节点流:具有实际传输数据的读写功能。

过滤流:在节点流的基础之上增强功能。

第二节:字节流

2.1字节流的父类(抽象类)

InputStream:字节输入流
输入方法:
public int read(){}
public int read(byte[] b){}
public int read(byte[] b,int off,int len){}

OutputStream:字节输出流
输出方法:
public void write(int n){}
public void write(byte[] b){}
public void write(byte[] b,int off,int len){}

2.2字节节点流

FileOutputStream:
public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。

FileInputStream:
public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。

2.3字节过滤流

缓冲流:BufferedOutputStream/BufferedInputStream
提高IO效率,减少访问磁盘的次数;
数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。

在这里插入图片描述

字节流示例代码:

//创建了字节节点流
		//绝对路径:F:\\1905\\1905所有内容\\代码\\Day21  
		//相对路径:与上面同理,  不过是相对项目的根目录下的路径
		//如果想在根目录下使用文件夹,自行创建。然后将指定的文件完整路径写清
		FileOutputStream fos = new FileOutputStream("Files\\Target.txt");
		
//		fos.write(65);
//		fos.write(66);
//		fos.write(67);
//		
//		fos.write('C');
		byte[] b = new byte[]{65,66,67,68,69};
		fos.write(b);
		
		//创建输入字节节点流
		FileInputStream fis = new FileInputStream("Files\\Target.txt");
		///每次读一个字节
//		int n = fis.read();
//		System.out.println((char)n);
		//将字节读到指定数组中
		byte[] b2 = new byte[1];
		int result = 0;
//		do{
//			result = fis.read(b2);
//			System.out.println(result);
//		}while(result != -1);
//		System.out.println("已到达文件末尾");
		
		while(true){
			result = fis.read(b2);
			if(result == -1){
				System.out.println("文件已到达末尾");
				break;
			}
			System.out.println(result);
		}
//		for(int i = 0 ; i<b2.length;i++){
//			System.out.println(b2[i]);
//		}
		//将指定内容输入到数组中,指定存入的下标以及长度
//		byte[] b3 = new byte[4];
//		fis.read(b3, 1, 3);
//		for(int i = 0 ;i<b3.length;i++){
//			System.out.println((char)b3[i]);
//		}
		
		

字节过滤流示例代码:

//1.创建字节节点流
		FileOutputStream fos = new FileOutputStream("Files\\Target.txt");
		//2.字节过滤流
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		bos.write('A');
		bos.write('B');
		bos.write('C');
		bos.write('D');
		bos.write('E');
		//刷新缓冲区,将缓冲区里的数据一次性输出到指定的文件中
		//bos.flush();
		//同理,也能flush缓冲区
		bos.close();
		//------------------BufferedInputStream
		//创建字节节点流   输入流
		FileInputStream fis = new FileInputStream("Files\\Target.txt");
		//创建字节过滤流  输入流
		BufferedInputStream bis = new BufferedInputStream(fis);
		//缓冲区
		byte[] b = new byte[4];
		
		while(true){
			//接收每次读到的内容个数
			int count = bis.read(b);
			System.out.println(count);
			//返回-1,说明已到达文件尾部,没有内容了
			if(count == -1){
				break;
			}
			//循环办理缓冲区的内容,循环次数由,每次读到的个数决定!
			//注意:如果不确定文件内容,直接使用缓冲区数组的长度决定打印次数!可能会造成最后一次打印出现上一次的部分结果!
			for(int i = 0; i<count;i++){
				System.out.print((char)b[i]);
			}
			System.out.println();
		}

第三节:对象流

对象流:ObjectOutputStream/ObjectInputStream

增强了缓冲区功能

增强了读写8种基本数据类型和字符串功能

增强了读写对象的功能:

readObject() 从流中读取一个对象

writeObject(Object obj) 向流中写入一个对象

3.1使用对象流

若使用对象流,必须实现对象序列化:  implements  Serializable
否则运行会抛出异常:java.io.NotSerializableException

对象序列化细节:
    必须实现Serializable接口。
    必须保证其所有属性均可序列化。
    transient修饰为临时属性,不参与序列化。
    读取到文件尾部的标志:java.io.EOFException。 

示例代码:

//创建字节节点流
		FileOutputStream fos = new FileOutputStream("Files\\object.txt");
		//创建对象过滤流
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		//往文件写对象。前提是自定义的对象支持序列化
		oos.writeObject(new Student("Tom",20,"男",100D,new Address()));
		oos.writeObject(new Student("marry",22,"女",80D,new Address()));
		oos.writeObject(new Student("Gavin",21,"男",50D,new Address()));
		//刷新 提交
		oos.flush();
		//----------------将对象已经持久化存储在文件里。------------------------
		//----------------将对象通过反序列化,读取文件里的对象--------
		//创建字节节点流  输入
		FileInputStream fis = new FileInputStream("Files\\object.txt");
		//创建对象过滤流   输入
		ObjectInputStream ois = new ObjectInputStream(fis);
		
		for(;;){
			try {
				//通过反序列化实现对文件里的对象  做读入
				Object obj = ois.readObject();
				System.out.println(obj.toString());
			} catch (EOFException e) {//对象输入流特殊性:到达尾部时,不是-1,而是EOFException。
				System.out.println("已到达文件末尾!没有内容了!");
				break;//break可以写在catch块里!
			}
			
		}
	}
}
//自定义对象变成可序列化
class Student implements Serializable{
	String name;
	Integer age;
	String sex;
	Double score;
	transient Address address;//如果某些属性不参与序列化。可以使用transient修饰为临时属性即可
	public Student(String name, Integer age, String sex, Double score,Address address) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.score = score;
		this.address = address;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", sex=" + sex + ", score=" + score+",Address = "+address + "]";
	}
}
class Address{
	String position;
	String email;
}

第四节:字符编码

ISO-8859-1	收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。
UTF-8	针对Unicode的可变长度字符编码
GB2312	简体中文
GBK		简体中文、扩充
BIG5	台湾,繁体中文 

当编码方式和解码方式不一致时,会出现乱码

示例:
		String s = "你好世界abc123喆";
		//把字符串转换为字节
		byte[] b = s.getBytes();
		for(int i = 0;i<b.length;i++){
			System.out.println(b[i]);
		}
		//--------------以上内容,将字符串内容转为字节,出现错误!------------
		//转换GBK
		String s1 = new String(b,"GBK");
		System.out.println(s1);
		//转换  big5
		String s2 = new String(b,"BIG5");
		System.out.println(s2);

第五节:字符流

字符流的父类(抽象类)


Reader:字符输入流
常用方法:
public int read(){}
public int read(char[]  c){}
public int read(char[] b,int off,int len){}

Writer:字符输出流
public void write(int n){}
public void write(String str){}
public void write(char[] c){}

5.1字符节点流

FileWriter:
public void write(String str) //一次写多个字符,将b数组中所有字符,写入输出流。

FileReader:
public int read(char[] c) //从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1。



示例:
//创建了字符节点流
		Writer w = new FileWriter("Files\\chars.txt");
		
		w.write("HelloWorld");
		
		w.write("HelloWorld");
		w.write("abc");
		w.flush();
		//----------------------------------------------
		Reader r = new FileReader("Files\\chars.txt");
		//定义char数组  接收输入的每个字符
		char[] chars = new char[5];
		//使用死循环,重复去文件中读取内容到缓冲区里
		for(;;){
			//由于缓冲区只有5个空间,所以每次读取只能拿到5个内容,所以需要多次执行read拿多次5个内容
			 int count = r.read(chars);
			if(count == -1)break;
			for(int i = 0;i<count;i++){
				System.out.print(chars[i]);
			}
			System.out.println();
		}
	}

5.2字符过滤流

缓冲流:BufferedWriter/BufferedReader
支持输入换行符。
可一次写一行、读一行。 

PrintWriter:
封装了print() / println()方法,支持写入后换行。



示例:
	//1.先有字符字节流
		Writer w = new FileWriter("Files\\b.txt");
		//2。创建字符过滤流
		//BufferedWriter bw = new BufferedWriter(w);
//		bw.write("HelloWorld");
//		bw.newLine(); //  ====  \n
//		bw.write("dadadadada");
//		bw.flush();
		//PrintWriter类    与之前使用的打印语句 毫无差别!
		//相比BufferedWriter,使用上来说更便捷。
		PrintWriter print = new  PrintWriter("Files\\b.txt");
		print.print("HelloWolrd");
		print.println("dadadadadadadadadada");//=====bw.write()之后bw.newLine();
		print.flush();
		
		
		
		
		
		//--------------------------------------------------
		Reader r = new FileReader("Files\\b.txt");
		BufferedReader br = new BufferedReader(r);
		System.out.println(br.readLine());//能直接读取一行内容
		System.out.println(br.readLine());
		System.out.println(br.readLine());//当读取的行没有数据,返回NULL
	}

5.3桥转换流

 InputStreamReader/OutputStreamWriter
可将字节流转换为字符流。
可设置字符的编码方式。


示例:

	//创建字节节点流
		FileOutputStream fos = new FileOutputStream("Files\\convet.txt");
		
		//创建   将字节节点流转换为字符节点流。
		OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
		
		//接着包装,    创建字符过滤流
		PrintWriter pw = new PrintWriter(osw);
		
		pw.print('A');
		pw.print(65);//不再将65作转换,  直接当成字符串
		pw.println("哒哒哒哒哒哒哒哒");
		pw.println("游戏开心为主");
		pw.println("Night Life");
		pw.println("温存");
		
		pw.flush();
		
		//---------------------------------------输入-------------------------
		FileInputStream fis = new FileInputStream("Files\\convet.txt");//字节
		InputStreamReader isr = new InputStreamReader(fis);//字符
		//PrintWriter只跟BufferedWriter有关系。  
		//正常使用字符的过滤流  还是要使用BufferedReader
		BufferedReader br = new BufferedReader(isr);//字符过滤
		for(;;){
			String s = br.readLine();
			if(s == null){
				break;
			}
			System.out.println(s);
		}
		

5.4总结使用步骤:

创建节点流
[创建过滤流 设置字符编码集]
封装过滤流
读写数据
关闭流 

ileInputStream(“Files\convet.txt”);//字节
InputStreamReader isr = new InputStreamReader(fis);//字符
//PrintWriter只跟BufferedWriter有关系。
//正常使用字符的过滤流 还是要使用BufferedReader
BufferedReader br = new BufferedReader(isr);//字符过滤
for(;😉{
String s = br.readLine();
if(s == null){
break;
}
System.out.println(s);
}


### 5.4总结使用步骤:

```java
创建节点流
[创建过滤流 设置字符编码集]
封装过滤流
读写数据
关闭流 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值