Day24

Day24

字符流

应用场景:处理纯文本数据
abstract class Reader -- 字符输入流(字符流的基类)

abstract class Writer -- 字符输出流(字符流的基类)
class InputStreamReader extends Reader -- 字符输入转换流(将字节流转换为字符流)

class OutputStreamWriter extends Writer -- 字符输出转换流(将字节流转换为字符流)

注意:

  1. 将字节流转换为字符流,用于传输文本数据
  2. 字符流要加上编码格式,防止乱码
  3. 字符流底层是字节流+编码器
    class FileReader extends InputStreamReader -- 文件字符输入流

class FileWriter extends OutputStreamWriter -- 文件字符输出流
class BufferedReader extends Reader -- 带缓冲区的字符输入流

class BufferedWriter extends Writer -- 带缓冲区的字符输出流

缓冲区大小:8192字符 -- new char[8192]

使用:当需要将字节文件转换为字符的时候,用OutputStreamReader和OutputStreamWriter,或以OutputStreamReader和OutputStreamWriter为参数的BufferedWriter和BufferedReader;

当使用平台默认字符编码,处理小文件或对性能要求不高的场景需要从文件里读取和获取字符内容时,用以FileWriter和FileReader作为参数的BufferedWriter和BufferedReader。

java 复制代码
//文件字节输出流 -> 字符输出转换流 -> 带缓冲区的字符输出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("123.txt", true)));

//文件字符输出转换流 -> 带缓冲区的字符输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("123.txt"));

Reader InputStreamReader FileReader Writer OutputStreamWriter FileWriter BufferedReader BufferedWriter

字符输出转换流 与 字符输入转换流

知识点:利用 字符输出转换流 向文件写入数据

1)不处理异常的情况

2)文件存在的情况

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("hhy.txt"));
		//1.创建流对象 + 在末尾追加 + 使用默认编码格式
		//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("hhy.txt",true));
		
		//1.创建流对象 + 在末尾追加 + 使用指定编码格式
		//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("hhy.txt",true),Charset.forName("GBK"));
//		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("hhy.txt",true),"UTF-8");
    
		//2.写入数据
		//osw.write(97);//写入Unicode码
		
		//char[] cs = {'1','2','3','a','b','c','木','头','人'};
		//osw.write(cs);//写入字符数组
		//osw.write(cs, 3, 3);//写入字符数组,偏移量,写入长度
		
		String str = "123abc木头人";
		osw.write(str);//写入字符串
		//osw.write(str, 3, 3);//写入字符串,偏移量,写入长度
		
		//3.关闭资源
		osw.close();
		
	}

3)文件不存在的情况

经验:所有的输出流,当文件不存在时,都会创建文件,再写入数据。

4)处理异常的情况

java 复制代码
public static void main(String[] args) {
		
		
		OutputStreamWriter osw = null;
		try {
			//1.创建流对象 + 在末尾追加 + 使用指定编码格式
			osw = new OutputStreamWriter(new FileOutputStream("hhy.txt",true),"GBK");
			//2.写入数据
			osw.write("123abc木头人");
			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//3.关闭资源
			if(osw != null){
				try {
					osw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

知识点:利用 字符输入转换流 读取文件里的数据

1)不处理异常的情况

2)文件存在的情况

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		InputStreamReader isr = new InputStreamReader(new FileInputStream("hhy.txt"));
		
		//2.读取数据
		//read():读取字符的Unicode码,读取到文件末尾就返回-1
		int read;
		while((read = isr.read()) != -1){
			System.out.println((char)read);
		}
		
		//3.关闭资源
		isr.close();
		
		
	}

3)文件不存在的情况

经验:

所有的输出流,当文件不存在时,都会创建文件,再写入数据

所有的输入流,当文件不存在时,都会报错 - FileNotFoundException

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象 + 使用默认的编码格式
//		InputStreamReader isr = new InputStreamReader(new FileInputStream("hhy.txt"));
		
		//1.创建流对象 + 使用自定义的编码格式
//		InputStreamReader isr = new InputStreamReader(new FileInputStream("hhy.txt"),Charset.forName("GBK"));
		InputStreamReader isr = new InputStreamReader(new FileInputStream("hhy.txt"),"GBK");
		
		//2.读取数据
		//isr.read(cs):读取cs数组长度的数据,并把数据存入到数组中,返回有效字节数,读取到文件末尾则返回-1
		char[] cs = new char[1024];
		int len;
		while((len = isr.read(cs)) != -1){
			System.out.println(new String(cs, 0, len));
		}
		
		//3.关闭资源
		isr.close();
		
		
	}

4)处理异常的情况

java 复制代码
public static void main(String[] args){

		InputStreamReader isr = null;
		try {
			//1.创建流对象 + 使用自定义的编码格式
			isr = new InputStreamReader(new FileInputStream("hhy.txt"),"GBK");
			//2.读取数据
			//isr.read(cs):读取cs数组长度的数据,并把数据存入到数组中,返回有效字节数,读取到文件末尾则返回-1
			char[] cs = new char[1024];
			int len;
			while((len = isr.read(cs)) != -1){
				System.out.println(new String(cs, 0, len));
			}

			
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//3.关闭资源
			if(isr != null){
				try {
					isr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

文件字符输出流 与 文件字符输入流

知识点:利用 文件字符输出流 向文件写入数据

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		//FileWriter fw = new FileWriter("hhy.txt");
		
		//1.创建流对象 + 在文件末尾追加
		FileWriter fw = new FileWriter("hhy.txt",true);
		
		//2.写入数据
		fw.write("123abc木头人");
		
		//3.关闭资源
		fw.close();
	}

知识点:利用 文件字符输入流 读取文件里的数据

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		FileReader fr = new FileReader("hhy.txt");
		
		//2.读取数据
		char[] cs = new char[1024];
		int len;
		while((len = fr.read(cs)) != -1){
			System.out.println(new String(cs, 0, len));
		}
		
		//3.关闭资源
		fr.close();
	}

拷贝:

java 复制代码
public class Copy {

	public static void main(String[] args) throws IOException {
		
		FileReader fr = new FileReader("小说.txt");
		FileWriter fw = new FileWriter("copy.txt");
		
		char[] cs = new char[1024];
		int len;
		while((len = fr.read(cs)) != -1){
			fw.write(cs, 0, len);
		}
		
		fr.close();
		fw.close();
	}
}

带缓冲区的字符输出流 与 带缓冲区的字符输入流

知识点:利用 带缓冲区的字符输出流 向文件写入数据

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象(文件字节输出流 -> 字符输出转换流 -> 带缓冲区的字符输出流)
		//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("hhy.txt"), "GBK"));
		
		//1.创建流对象(文件字节输出流 -> 字符输出转换流 -> 带缓冲区的字符输出流) + 末尾追加
		//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("hhy.txt",true), "GBK"));
		
		//1.创建流对象(文件字符输出流 -> 带缓冲区的字符输出流)
		//BufferedWriter bw = new BufferedWriter(new FileWriter("hhy.txt"));
		
		//1.创建流对象(文件字符输出流 -> 带缓冲区的字符输出流) + 末尾追加
		BufferedWriter bw = new BufferedWriter(new FileWriter("hhy.txt",true));
		
		//2.写入数据
		bw.write("123abc木头人");
		
		//3.关闭资源
		bw.close();
	}

知识点:利用 带缓冲区的字符输入流 读取文件里的数据

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象(文件字节输入流 -> 字符输入转换流 ->  带缓冲区的字符输入流)
		//BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("hhy.txt"), "GBK"));
		
		//1.创建流对象(文件字符输入流 ->  带缓冲区的字符输入流)
		BufferedReader br = new BufferedReader(new FileReader("hhy.txt"));
				
		
		//2.读取数据
		char[] cs = new char[1024];
		int len;
		while((len = br.read(cs)) != -1){
			System.out.println(new String(cs, 0, len));
		}
		
		//3.关闭资源
		br.close();
	}

拷贝:

全文

java 复制代码
public class Copy01 {

	public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new FileReader("小说.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("copy.txt"));
		
		char[] cs = new char[1024];
		int len;
		while((len = br.read(cs)) != -1){
			bw.write(cs, 0, len);
		}
		
		br.close();
		bw.close();
	}
}

分行:

java 复制代码
public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new FileReader("小说.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("copy.txt"));
		
		
		//readLine()读取一行数据
		
		boolean flag = false;
		String readLine;
		while((readLine = br.readLine()) != null){
			if(flag){
				bw.newLine();//换行
			}
			bw.write(readLine);
			flag = true;
		}
		
		br.close();
		bw.close();
	}

对象流

理解:将对象写入到文件,将文件里的对象读取到程序中
class ObjectInputStream -- 对象输入流

class ObjectOutputStream -- 对象输出流
序列化/钝化:程序里的对象 写入到 文件中

反序列化/活化:文件中的对象 读取到 程序中
注意:

  1. 对象所属的类必须实现序列化接口 - Serializable
  2. Serializable接口没有任何抽象方法
  3. 没有任何抽象方法的接口叫做标记型接口
  4. Serializable的实现类必须添加序列化ID - serialVersionUID
  5. transient修饰的成员属性,该属性不会随着对象写入到文件中
  6. 静态属性不会随着对象写入到文件中,因为静态属性不属于对象
    知识点:利用 对象输出流 向文件写入数据
java 复制代码
public static void main(String[] args) throws FileNotFoundException, IOException {
		
		//1.创建流对象
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("hhy.txt"));
		
		//2.写入数据
		oos.writeInt(100);//写入int类型的数据
		oos.writeDouble(123.123);//写入double类型的数据
		oos.writeUTF("用良心做教育");//写入UTF-8编码格式的字符串类型的数据
		oos.writeObject(new Date());//写入对象类型的数据
		
		//3.关闭资源
		oos.close();
	}

知识点:利用 对象输入流 读取文件里的数据

java 复制代码
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
		//1.创建流对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("hhy.txt"));
		
		//2.写入数据(注意:读取顺序必须和写入顺序一致)
		int readInt = ois.readInt();
		double readDouble = ois.readDouble();
		String readUTF = ois.readUTF();
		Date date = (Date) ois.readObject();
		System.out.println(readInt);
		System.out.println(readDouble);
		System.out.println(readUTF);
		System.out.println(date);
		
		//3.关闭资源
		ois.close();
	}

知识点:利用 对象输出流 向文件写入自定义对象

java 复制代码
import java.io.Serializable;

public class User implements Serializable{

	private static final long serialVersionUID = 8798250558176997713L;
	
	private String username;
	private transient String password;
	private String nickName;
	private String role;
	private double hp;
	private double mp;
	
	public User() {
	}

	public User(String username, String password, String nickName, String role, double hp, double mp) {
		this.username = username;
		this.password = password;
		this.nickName = nickName;
		this.role = role;
		this.hp = hp;
		this.mp = mp;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getNickName() {
		return nickName;
	}

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}

	public String getRole() {
		return role;
	}

	public void setRole(String role) {
		this.role = role;
	}

	public double getHp() {
		return hp;
	}

	public void setHp(double hp) {
		this.hp = hp;
	}

	public double getMp() {
		return mp;
	}

	public void setMp(double mp) {
		this.mp = mp;
	}

	@Override
	public String toString() {
		return "User [username=" + username + ", password=" + password + ", nickName=" + nickName + ", role=" + role
				+ ", hp=" + hp + ", mp=" + mp + "]";
	}
}
java 复制代码
public static void main(String[] args) throws FileNotFoundException, IOException {
		
		//1.创建流对象
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("hhy.txt"));
		
		//2.写入数据
		oos.writeObject(new User("1111111179", "123123", "撕裂的忧伤", "艾瑞莉娅", 1200, 800));
		oos.writeObject(new User("2333333330", "321321", "沙漠野猪", "DJ", 1000, 1000));
		oos.writeObject(new User("1234532143", "123456", "玛卡巴卡", "元歌", 800, 1200));
		
		//3.关闭资源
		oos.close();
	}

知识点:利用 对象输入流 读取文件里的自定义对象

java 复制代码
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		
		//1.创建流对象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("hhy.txt"));
		
		//2.写入数据(注意:读取顺序必须和写入顺序一致)
		try {
			User user;
			while((user = (User) ois.readObject()) != null){
				System.out.println(user);
			}
		} catch (EOFException e) {
		}
		
		
		//3.关闭资源
		ois.close();
	}

内存流

理解:以前我们学习的流是内存(程序)到硬盘(文件)的通道,内存流是程序到内存的通道。内存流是将数据存储到内存里,所以他是非数据持久化
class ByteArrayInputStream -- 内存输入流

class ByteArrayOutputStream -- 内存输出流

注意:内存流是程序到内存的通道,是关闭不掉的
知识点:内存输出流

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		
		//关闭资源(注意:内存流是程序到内存的通道,是关闭不掉的)
		baos.close();
		
		//2.写入数据
		baos.write("123abc木头人".getBytes());
		
		//获取数据
		byte[] byteArray = baos.toByteArray();
		System.out.println(new String(byteArray));
		
		String str = baos.toString();
		System.out.println(str);
	}

知识点:内存输入流

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		ByteArrayInputStream bais = new ByteArrayInputStream("123abc木头人".getBytes());
		
		//关闭资源(注意:内存流是程序到内存的通道,是关闭不掉的)
		bais.close();
		
		//2.读取数据
		byte[] bs = new byte[1024];
		int len;
		while((len = bais.read(bs)) != -1){
			System.out.println(new String(bs,0,len));
		}
	}

打印流

理解:打印流是程序到文件,只有一个方向
class PrintStream -- 字节打印流

class PrintWriter -- 字符打印流(底层是由字节打印流实现的)
PrintStream vs PrintWriter

PrintStream:可以将字节流转换为字节打印流

PrintWriter :可以将字节流、字符流转换为字符打印流
知识点:字节打印流

java 复制代码
public static void main(String[] args) throws FileNotFoundException {
		
		//1.创建流对象
		//PrintStream ps = new PrintStream("hhy.txt");
		
		//1.创建流对象(将字节流转换为字节打印流)
		//PrintStream ps = new PrintStream(new FileOutputStream("hhy.txt"));
		
		//1.创建流对象(将字节流转换为字节打印流) + 末尾追加
		PrintStream ps = new PrintStream(new FileOutputStream("hhy.txt", true));
		
		//2.写入数据
		ps.println("用良心做教育");
		
		//3.关闭资源
		ps.close();
	}

知识点:字符打印流

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		//PrintWriter pw = new PrintWriter("hhy.txt");
		
		//1.创建流对象(将字节流转换为字符打印流)
		//PrintWriter pw = new PrintWriter(new FileOutputStream("hhy.txt"));
		
		//1.创建流对象(将字节流转换为字符打印流) + 末尾追加
		//PrintWriter pw = new PrintWriter(new FileOutputStream("hhy.txt", true));
		
		//1.创建流对象(将字符流转换为字符打印流)
		//PrintWriter pw = new PrintWriter(new FileWriter("hhy.txt"));
		
		//1.创建流对象(将字符流转换为字符打印流) + 末尾追加
		PrintWriter pw = new PrintWriter(new FileWriter("hhy.txt",true));
		
		//2.写入数据
		pw.println("用良心做教育");
		
		//3.关闭资源
		pw.close();
	}

重定向

重定向

System.setIn(new FileInputStream("hhy.txt")); -> 重定向后(方向:文件->程序)

InputStream in = System.in; -> 系统标准的输入流(方向:控制台->程序)

System.setOut(new PrintStream("hhy.txt"));->重定向后(方向:程序->文件)

PrintStream ps = System.out; -> 系统标准的输出流(方向:程序->控制台)

System.setErr(new PrintStream("hhy.txt"));->重定向后(方向:程序->文件)

PrintStream ps = System.err; -> 系统标准的错误输出流(方向:程序->控制台)

java 复制代码
public static void main(String[] args) throws FileNotFoundException {
		
		//重定向后(方向:文件->程序)
		System.setIn(new FileInputStream("hhy.txt"));
		
		//系统标准的输入流(方向:控制台->程序)
		InputStream in = System.in;
		Scanner scan = new Scanner(in);
		
		String string = scan.next();//不是从控制台输入,而是从文件中读取
		System.out.println(string);
		
		scan.close();
		
	}
java 复制代码
public static void main(String[] args) throws FileNotFoundException {
		
		//重定向后(方向:程序->文件)
		System.setOut(new PrintStream(new FileOutputStream("hhy.txt", true)));
		
		//系统标准的输出流(方向:程序->控制台)
		PrintStream ps = System.out;
		
		ps.println("用良心做教育");
		
	}
java 复制代码
public static void main(String[] args) throws FileNotFoundException {
		
		//重定向后(方向:程序->文件)
		System.setErr(new PrintStream(new FileOutputStream("hhy.txt", true)));
		
		//系统标准的错误输出流(方向:程序->控制台)
		PrintStream ps = System.err;
		
		ps.println("用良心做教育");
		
	}

随机访问流

理解:该流认为文件是一个大型的byte数组,该流有一个隐藏的指针(默认为0),可以从指针开始读取或写入(该流有两个方向),模式r为读,模式rw为写。可以设置指针的位置。

知识点:利用 随机访问流 将数据写入到文件

1)写入数字、英文、中文

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		RandomAccessFile w = new RandomAccessFile("hhy.txt", "rw");
		
		//2.写入数据
		w.write("123abc木头人".getBytes());
		
		//3.关闭资源
		w.close();
	}

2)在文件末尾追加

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		File file = new File("hhy.txt");
		RandomAccessFile w = new RandomAccessFile(file, "rw");
		
		//设置指针
		w.seek(file.length());
		
		//2.写入数据
		w.write("123abc木头人".getBytes());
		
		//3.关闭资源
		w.close();
	}

知识点:利用 随机访问流 读取文件里的数据

1)读取数据

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		RandomAccessFile r = new RandomAccessFile("hhy.txt", "r");
		
		
		//2.读取数据
		byte[] bs = new byte[1024];
		int len;
		while((len = r.read(bs)) != -1){
			System.out.println(new String(bs, 0, len));
		}
		
		//3.关闭资源
		r.close();
	}

2)从英文处开始读取

java 复制代码
public static void main(String[] args) throws IOException {
		
		//1.创建流对象
		RandomAccessFile r = new RandomAccessFile("hhy.txt", "r");
		
		//设置指针
		r.seek(3);
		
		//2.读取数据
		byte[] bs = new byte[1024];
		int len;
		while((len = r.read(bs)) != -1){
			System.out.println(new String(bs, 0, len));
		}
		
		//3.关闭资源
		r.close();
	}

知识点:拷贝文件 -- 断点续传

java 复制代码
public static void main(String[] args) throws IOException {
		
		RandomAccessFile r = new RandomAccessFile("源文件.mp4", "r");
		
		File targetFile = new File("copy.mp4");
		RandomAccessFile w = new RandomAccessFile(targetFile, "rw");
		
		//设置指针 -- 断点续传
		long length = targetFile.length();
		r.seek(length);
		w.seek(length);
		
		byte[] bs = new byte[1024];
		int len;
		while((len = r.read(bs)) != -1){
			w.write(bs, 0, len);
		}
		
		r.close();
		w.close();
	}

提升方向:

BIO(目前学习的) -> NIO -> AIO

相关推荐
我焦虑的编程日记1 天前
【RabbitMQ】RabbitMQ学习
java·数据库·java-ee
阿华的代码王国4 天前
【JavaEE】——线程池大总结
java·开发语言·jvm·java-ee
计算机程序设计开发5 天前
基于Node.js+Express+MySQL+VUE科研成果网站发布查看科研信息科研成果论文下载免费安装部署
数据库·spring boot·mysql·java-ee·课程设计·计算机毕设·计算机毕业设计
计算机专业源码5 天前
基于J2EE技术的高校社团综合服务系统
java·java-ee
阿华的代码王国5 天前
【JavaEE】——多线程常用类和常用数据结构(精华长文)
java·开发语言·java-ee
Yhame.6 天前
Java EE中的编码问题及解决方案
java·java-ee
逸狼7 天前
【JavaEE初阶】文件IO(下)
java·java-ee
matrixlzp7 天前
IDEA 高版本创建 Spring Boot 项目选不到 java 8
java·java-ee·intellij-idea
panjyash8 天前
JAVAEE如何实现网页(jsp)间的数据传输?一文总结
java·java-ee
月临水9 天前
JavaEE: 深入探索TCP网络编程的奇妙世界(四)
网络·tcp/ip·java-ee