IO流(20210907)

操作流的基本步骤

1.创建源 2.选择流 3.操作(读入) 4.释放资源

一.节点流

从一个特定的数据源(节点)读写数据(如:文件、内存)的类叫做节点流类。在这里插入图片描述

1.文件字节流
  • 1.1字节输入流 FileInputStream
    步骤:1.创建源 ;2.选择流; 3.操作(读入);4.释放资源
	public static void main(String[] args) {
		// 1.创建源
		File src = new File("D:/workspace/stsworkspace/IO_study02/src/abc.txt");
		// 2.选择流
		InputStream is = null;
		try {
			is = new FileInputStream(src);
			// 3.操作
			// 缓冲容器-字节数组
			byte[] flush = new byte[1024 * 10];
			// 接收长度
			int len = -1;

			while ((len = is.read(flush)) != -1) {
				// 字节数组-->字符串(解码)
				String str = new String(flush, 0, len);
				System.out.println(str);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if (null != is) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

  • 1.2字节输出流 FileOutputStream
    1.创建源 2.选择流 3.操作(写出内容) 4.释放资源
	public static void main(String[] args) {
		// 1.创建源
		File dest = new File("dest.txt");
		// 2.选择流
		OutputStream os = null;
		try {
			//true:在原来的数据后面是追加写入
			//false:将原来的数据删掉,重写写入
			os = new FileOutputStream(dest,true);
			
			//3.操作(写出)
			String msg = "IO is so easy";
			//字符串-->字节数组(编码)
			byte[] datas = msg.getBytes();
			os.write(datas,0,datas.length);
			os.flush();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != os) {
					os.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

  • 1.3文件copy
	public static void main(String[] args) {

		// 1.创建源
		//输入源
		File inputSrc = new File("abc.txt");
		//输出源
		File outputSrc = new File("abc_cop.txt");
		
		// 2.选择流
		InputStream is = null;
		OutputStream os = null;
		
		try {
			is = new FileInputStream(inputSrc);
			os = new FileOutputStream(outputSrc,true);
			
			// 3.操作
		
			// 缓冲容器-字节数组(分段读取)
			byte[] flush = new byte[1024 * 10];
			// 接收长度
			int len = -1;

			while ((len = is.read(flush)) != -1) {
				
//				// 字节数组-->字符串(解码)
//				String str = new String(flush, 0, len);
//				
//				// 字符串-->字节数组(编码)
//				byte[] datas = str.getBytes();
//				以上代码可以省略,由于is.read(flush)方法执行结束后,
//				不仅返回接受长度,还会将内容存入字节数组(更新fulsh),
//				所以在write方法中直接使用即可;
				
				os.write(flush,0,len);
				os.flush();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.释放资源 分别关闭 先打开的后关闭
			try {
				if (null != os) {
					os.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (null != is) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
2.文件字符流
  • 2.1字符输入流 FileReader
	public static void main(String[] args) {
		// 1.创建源
		File src = new File("D:/workspace/stsworkspace/IO_study02/abc.txt");
		// 2.选择流
		Reader reader = null;
		try {
			reader = new FileReader(src);
			// 3.操作
			// 缓冲容器-字节数组
			char[] flush = new char[1024];
			// 接收长度
			int len = -1;

			while ((len = reader.read(flush)) != -1) {
				// 字节数组-->字符串
				String str = new String(flush, 0, len);
				System.out.println(str);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(null!=reader) {
					reader.close();
				}
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}
  • 2.2字符输出流 FileWriter
	public static void main(String[] args) {
		// 1.创建源
		File dest = new File("dest.txt");
		// 2.选择流
		Writer writer = null;
		try {
			
			writer = new FileWriter(dest);
			
			//3.操作(写出)
			String msg = "IO is so easy 文件字符输出流aaa";
			//写法一
			//字符串-->字节数组
//			char[] datas = msg.toCharArray();
//			
//			writer.write(datas,0,datas.length);
//			writer.flush();
			
			//写法二
			writer.write(msg);
			writer.write("append");
			writer.flush();
			
			//写法三
			writer.append(msg).append("append");
			writer.flush();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != writer) {
					writer.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
3.文件字节数组流
  • 3.1字节数组输入流 ByteArrayInputStream
    步骤: 1.创建源:字节数组; 2.选择流; 3.操作; 4.释放资源:可以不处理
	public static void main(String[] args) {
		// 1.创建源
		byte[] src = "talk is cheap show me the code".getBytes();
		// 2.选择流
		InputStream is = null;
		try {
			is = new ByteArrayInputStream(src);
			// 3.操作(分段读取)
			// 缓冲容器-字节数组
			byte[] flush = new byte[5];
			// 接收长度
			int len = -1;

			while ((len = is.read(flush)) != -1) {
				// 字节数组-->字符串
				String str = new String(flush, 0, len);
				System.out.println(str);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//字节数组可以不释放内存
			try {
				if (null != is) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
  • 3.2字节数组输出流 ByteArrayOutputStream
    步骤: 1.创建源:内部维护; 2.选择流:不关联源; 3.操作:(写出内容);4.释放资源:可以不处理
	public static void main(String[] args) {
		// 1.创建源
		byte[] dest = null;
		// 2.选择流
		ByteArrayOutputStream baos = null;
		try {
			baos = new ByteArrayOutputStream();
			
			//3.操作(写出)
			String msg = "show me the code";
			//字符串-->字节数组(编码)
			byte[] datas = msg.getBytes();
			baos.write(datas,0,datas.length);
			baos.flush();
			//获取数据
			dest = baos.toByteArray();
			System.out.println(dest.length
					+ "-->" + new String(dest,0,baos.size()));
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != baos) {
					baos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
二.处理流

只用字节或是字符为单位来对数据做输入输出是不够的,有时候我们需要一行一行的读数据,有时我们需要读取特定格式的数据,因此Java提供了这样的机制,能把数据流作连接(chain),让原本没有特殊访问方法的流,通过连接到特殊的流后,变成可以用特定的方法来访问数据
在这里插入图片描述

1.字节缓冲流

提升性能,建议在所有流外面都套一个。

  • 1.1字节缓冲输入流 BufferedInputStream
	public static void main(String[] args) {
		// 1.创建源
		File src = new File("abc.txt");
		// 2.选择流
		InputStream is = null;
		try {
			is = new BufferedInputStream(new FileInputStream(src));
			// 3.操作(分段读取)
			// 缓冲容器-字节数组
			byte[] flush = new byte[1024];
			// 接收长度
			int len = -1;

			while ((len = is.read(flush)) != -1) {
				// 字节数组-->字符串
				String str = new String(flush, 0, len);
				System.out.println(str);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//字节数组可以不释放内存
			try {
				if (null != is) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
  • 1.2字节缓冲输出流 BufferedOutputStream
	public static void main(String[] args) {
		// 1.创建源
		File dest = new File("destbuffer.txt");
		// 2.选择流
		OutputStream os = null;
		try {
			os = new BufferedOutputStream(new FileOutputStream(dest)) ;
			
			//3.操作(写出)
			String msg = "IO is so easy ,BufferedOutputStream";
			//字符串-->字节数组(编码)
			byte[] datas = msg.getBytes();
			os.write(datas,0,datas.length);
			os.flush();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != os) {
					os.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
2.字符缓冲流
  • 2.1 字符缓冲输入流 BufferedReader
	public static void main(String[] args) {
		// 1.创建源
		File src = new File("D:/workspace/stsworkspace/IO_study02/abc.txt");
		// 2.选择流
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(src)) ;
			// 3.操作
			String line = null;
			//readLine():BufferedReader新方法,所以第20行不能使用多态
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(null!=reader) {
					reader.close();
				}
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}
  • 2.2 字符缓冲输出流 BufferedWriter
	public static void main(String[] args) {
		// 1.创建源
		File dest = new File("dest.txt");
		// 2.选择流
		BufferedWriter writer = null;
		try {
			
			writer = new BufferedWriter(new FileWriter(dest)) ;
			
			//3.操作(写出)
			String msg = " 文件字符输出流";
			writer.append("IO is so easy");
			writer.newLine();
			writer.append("测试新方法newLine()");
			writer.flush();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != writer) {
					writer.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
3.转换流

转换流特点:以字符流的形式操作字节流(纯文本),可以指定字符集;

  • 3.1输入流 InputStreamReader
  • 3.2输出流 OutputStreamWriter
	public static void main(String[] args) {
		//操作System.in和System.out
		try(
		//括号中可以写多行语句,会自动关闭括号中的资源
			//将字节流(System.in)转换为字符流
			//"UTF-8"指定字符集
		BufferedReader reader = new BufferedReader (new InputStreamReader(System.in,"UTF-8"));
			//将字节流(System.out)转换为字符流
		BufferedWriter writer = new BufferedWriter (new OutputStreamWriter(System.out));
		){
			//循环获取键盘的输入(exit退出),输出此内容
			String msg = "";
			while(!msg.equals("exit")) {
				msg = reader.readLine();
				writer.write(msg);
				writer.newLine();
				writer.flush();//强制刷新
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
4.数据流 DataOutputStream DataInputStream

特点:保留了数据类型
要求:1.写出后读取;2.读取的顺序与写出保持一致

	public static void main(String[] args) throws IOException {
		//写出
		//声明字节流对象,以便使用其新增方法
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(baos));
		//操作数据类型 + 数据
		dos.writeUTF("编码心酸泪,谁解其中味");
		dos.writeInt(18);
		dos.writeBoolean(false);
		dos.writeChar('a');
		dos.flush();
		
		//任何数据都可以转换为字节数组
		byte[] datas = baos.toByteArray();
		//读取
		DataInputStream dis = new DataInputStream(
				new BufferedInputStream(new ByteArrayInputStream(datas)));
		//顺序与写出一致
		String msg = dis.readUTF();
		int age = dis.readInt();
		boolean flag = dis.readBoolean();
		char ch = dis.readChar();
		
		System.out.println(flag);
	}

5.对象流 ObjectOutputStream ObjectInputStream
  • 5.1对象流特点
    1.写出后读取;2.读取的顺序与写出保持一致;3.不是所有的对象都可以序列化,必须实现Serializable接口或Externalizable接口;
  • 5.2序列化
    对象(Object)序列化是指将对象转换为字节序列的过程;
    反序列化则是根据字节序列恢复对象的过程;
  • 5.3序列化一般用于以下场景
    ①永久性保存对象,保存对象的字节序列到本地文件中;
    ②通过序列化对象在网络中传递对象;
    ③通过序列化在进程间传递对象;
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//写出
		//声明字节流对象,以便使用其新增方法
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(baos));
		
		//操作对象
		oos.writeObject("编码心酸泪,谁解其中味");
		oos.writeObject(new Date());
		Emlpoyee emp = new Emlpoyee("马云",400);
		oos.writeObject(emp);
		oos.flush();
		
		//任何数据都可以转换为字节数组
		byte[] datas = baos.toByteArray();
		//读取
		ObjectInputStream ois = new ObjectInputStream(
				new BufferedInputStream(new ByteArrayInputStream(datas)));
		//顺序与写出一致
		Object str = ois.readObject();
		Object date = ois.readObject();
		Object emlpoyee = ois.readObject();
		
		if(str instanceof String){
			String strObj = (String)str;
			System.out.println(strObj);
		}
		
		if(date instanceof Date){
			Date dateObj = (Date)date;
			System.out.println(dateObj);
		}
		
		if(emlpoyee instanceof Emlpoyee){
			Emlpoyee empObj = ((Emlpoyee) emlpoyee);
			System.out.println(empObj.getName());
			System.out.println(empObj.getSalary());
		}
		
	}

被transient修饰的属性不会被序列化

class Emlpoyee implements java.io.Serializable{
	
	//transient指该数据不需要序列化
	private transient String name;
	private double salary;

	public Emlpoyee() {
		super();
	}
	
	public Emlpoyee(String name, double salary) {
		super();
		this.name = name;
		this.salary = salary;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}
	
}
6.打印流

	public static void main(String[] args) throws FileNotFoundException {
		PrintStream ps = System.out;
		ps.println("打印流");
		ps.println(true);
		
		ps = new PrintStream(new BufferedOutputStream(new FileOutputStream("print.txt")),true);
		ps.println("打印流");
		ps.println(true);
		ps.flush();
		ps.close();
		
		//重定向输出端
		System.setOut(ps);
		System.out.println("change");
		//重定向回控制台
		System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true));
		System.out.println("I am backing");
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值