Java学习笔记20(流Stream到底有哪些)

news/2024/7/24 2:25:10 标签: 字符串, java, 编程语言, stream

文章目录

  • 0.本篇摘要
  • 1.缓冲流
    • 1.1缓冲字节流
    • 1.2缓冲字符流
  • 2.转换流
    • 2.1转换输入流(字节->字符)
    • 2.2转换输出流(字节->字符)
  • 3.标准输入输出流
    • 3.1标准的输入流
  • 4.对象流
  • 5.RandomAccessFile 类
    • 随机读
    • 随机写

0.本篇摘要

字节流-缓冲流(重点)
输入流InputStream-FileInputStream-BufferedInputStream
输出流OutputStream-FileOutputStream-BufferedOutputStream

字符流-缓冲流(重点)
输入流Reader-FileReader-BufferedReader
输出流Writer-FileWriter-BufferedWriter

转换流
InputSteamReader和OutputStreamWriter

对象流(难点)
ObjectInputStream和ObjectOutputStream 序列化
反序列化
随机存取流RandomAccessFile(掌握读取、写入)

1.缓冲流

字节流,字符流,这种是计算机和硬盘之间的io, 读写速度慢。 缓冲流基于内存的io操作比基于硬盘的io操作快75000倍

BufferedInputStream 代替 FileInputStream
BufferedOutputStream 代替 FileOutputStream
BufferedReader 代替 FileReader
BufferedWriter 代替 FileWriter

在这里插入图片描述

基于内存的io操作比基于硬盘的io操作快75000倍

1.1缓冲字节流

BufferedInputStream 代替 FileInputStream
BufferedOutputStream 代替 FileOutputStream
代码示例:

java">import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Test {
	public static void main(String[] args) throws Exception {
		Test.testBufferedInputStream();
		Test.copyFile(inPath, outPath);//有参的方法,调用
	}
	/**
	 * 缓冲字节输入流
	 * BufferedInputStream
	 * @throws Exception
	 */
	public static void testBufferedInputStream() throws Exception {
		//文件字节输入流对象
		FileInputStream in = new FileInputStream("D:\\tt.txt");
		//把文件字节输入流放到缓冲字节输入流对象
		BufferedInputStream br = new BufferedInputStream(in);
		//因为是字节流,要定义byte数组存放
		byte[] b = new byte[10];
		
		//输出为字符串
		System.out.println(new String(b));
		
		//关闭流,先开后关。
		br.close();
		in.close();//去main方法中测试
		
	}

	/**
	 * 缓冲字节输出流
	 * BufferedOutputStream
	 */
	public static void testBufferedOutputStream() throws Exception{
		//创建字节输出流对象
		FileOutputStream out = new FileOutputStream("D:\\tt.txt");
		
		//把字节输出流对象放到缓冲字节输出流中
		BufferedOutputStream bo = new BufferedOutputStream(out);
		
		String s = "hello world";
		
		bo.write(s.getBytes());//写到内存中
		
		bo.flush();//刷到硬盘上
		
		//关闭流的时候,本着一个最晚开的最早关,依次关
		bo.close();
		out.close();
		
	}	
	
	
	public static void copyFile(String inPath, String outPath) throws Exception {
		
		BufferedInputStream br = new BufferedInputStream(new FileInputStream(inPath));//这里是采用匿名对象的方法
		
		BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(outPath));
		
		byte[] b = new byte[10];
		int len = 0;
		//设置一个没出读取到的数据的长度,直到br.read方法执行到最后(比如说文件中只有hello world,
//		执行到最后一个就读取d的后面,这个时候返回值就是-1)
		while((len = br.read(b)) != -1) {
			bo.write(b , 0, len);//写到内存
			bo.flush();
			bo.close();
			br.close();
			
		}
		
	}
	
	
}


1.2缓冲字符流

和上面的差不多,改几个代码就行。

把byte[] 改为char[]
使用BufferedReader, FileReader
BufferedWriter,FileWriter

2.转换流

所有的文件都是有编码格式
对于我们来说,TXT和java文件一般来讲有三种编码
ISO8859-1,西欧编码,是纯粹英文编码,不适应汉字
GBK和UTF-8,这两编码是适用于重要和英文
我们一般使用UTF-8编码

在eclipse上查看文件编码的方法:点击文件右键选择properties
在这里插入图片描述
Java API提供了两个转换流
InputStreamReaderOutputStreamWriter

2.1转换输入流(字节->字符)

知识点:
InputStreamReader in = new InputStreamReader(fs, “GBK”);//参数1是字节流,参数2是编码
注意,在转换字符流的时候,设置的字符集编码要与读取的文件的数据的编码一致

java">import java.io.FileInputStream;

import java.io.InputStreamReader;

public class Test2 {
	public static void main(String[] args) throws Exception {
		Test2.test();
		
	}
	/**
	 * 转换字节输入流为字符输入流,InputStreamReader(1,2),参数1是字节流对象,参数2是编码
	 * @throws Exception
	 */
	public static void test() throws Exception {
		FileInputStream fs = new FileInputStream("D:\\Program Files\\eclipse-workspace\\demo\\src\\day13\\tt.txt");
		
		InputStreamReader in = new InputStreamReader(fs, "GBK");//参数1是字节流,参数2是编码
		//注意,在转换字符流的时候,设置的字符集编码要与读取的文件的数据的编码一致
		
		char[] c = new char[100];
		int len = 0;
		while((len = in.read(c)) != -1) {
			System.out.println(new String(c, 0, len));
			
		}
		
		in.close();
		fs.close();
	}

}

2.2转换输出流(字节->字符)

java">/**
	 * 转换字节输出流为字符输出流
	 * 注意,在转换字符流的时候,设置的字符集编码要与读取的文件的数据的编码一致
	 * 不然就会出现乱码
	 * OutputStreamWriter
	 * @throws Exception 
	 */
	public static void testOutputStreamWriter() throws Exception {
		FileOutputStream fo = new FileOutputStream("D:\\Program Files\\eclipse-workspace\\demo\\src\\day13\\tt1.txt");
		
		OutputStreamWriter os = new OutputStreamWriter(fo, "GBK");
		
		//输出内容
		os.write("转换字节输出流为字符输出流");
		os.flush();
		os.close();
		fo.close();
		
		
	}

在main方法里面调用Test2.testOutputStreamWriter();

转换流:
1.可以把字节流转换为字符流
2.当字节流中的数据都是字符的时候,使用转换流转为字符流处理效率更高

3.标准输入输出流

System.out我们经常用,System.out.println(" ");
System.in;键盘输入

3.1标准的输入流

java">import java.io.BufferedReader;

import java.io.InputStreamReader;

public class Test3 {
	public static void main(String[] args) throws Exception {
		Test3.testSystemIn();
		
	}
	/**
	 * 标准的输入流
	 * @throws Exception
	 */
	public static void testSystemIn() throws Exception {
		//创建一个接收键盘输入数据的输入流
		InputStreamReader isr = new InputStreamReader(System.in);
		//把输入流放到缓冲流里
		BufferedReader br = new BufferedReader(isr);
		//定义一个临时接收数据的字符串
		String str = "";
		
		while((str =br.readLine()) != null) {
			System.out.println(str);
		}
		
		br.close();
		isr.close();
		

	}

}

个人觉得一个简单的输入,好麻烦呀

练习:把控制台输入的内容写到指定的TXT文件中,当接收到字符串over,就结束程序的运行

在上面的程序里面改一改就行,

1.要有输出流,用缓冲输出流, 输出的东西读入txt文件中
2.用if判断字符串,.equals(over)

java">/**
	 * 把控制台输入的内容写到指定的TXT文件中,当接收到字符串over,就结束程序的运行
	 */
	public static void write2TXT() throws Exception{
		//创建一个接收键盘输入数据的输入流
		InputStreamReader is = new InputStreamReader(System.in);
		
		//把输入流放到缓冲流里
		BufferedReader br = new BufferedReader(is);
		
		BufferedWriter out = new BufferedWriter(new FileWriter("D:\\testdemo\\demo\\src\\day13\\tt7.txt"));
		
		String line = "";
		
		while((line = br.readLine()) != null){
			if(line.equals("over")){
				break;
			}
			//读取的每一行都写到指定的TXT文件
			out.write(line);
		}
		
		out.flush();
		out.close();
		br.close();
		is.close();
		
	}

4.对象流

ObjectInputStream和OjbectOutputSteam

比如说:有一个汽车对象,把这个对象存在硬盘上,how?能像把大象装冰箱一样吗,打开冰箱门,装进去,然后关门。不可以。硬盘存数据的基础是二进制,那需要把对象转化二二进制的字节流。
再举一个例子,把汽车对象传送到另一台机器上,how?网络的基础是二进制,所以需要那需要把对象转化二二进制的字节流。

对象的持久化(保存到硬盘)
对象的网络传输

所以引入了对象流

序列化(Serialize):用ObjectOutputStream类将一个Java对象写入IO流中
反序列化(Deserialize):用ObjectInputStream类从IO流中恢复该Java对象
序列化,反序列化只针对对象的属性,和类的属性无关
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量

如果需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:
Serializable
Externalizable

java">import java.io.Serializable;

/**
 * 可以序列化与反序列化的对象
 * @author
 *
 */
public class Person implements Serializable{

	/**
	 * 一个表示序列化版本标识符的静态变量
	 * 用来表明类的不同版本间的兼容性
	 */
	private static final long serialVersionUID = 1L;
	
	public String name;
	public int age;

注意:对象的序列化与反序列化使用的类要严格一致,包名,类名,类机构等等所有都要一致

创建一个 ObjectOutputStream
调用 ObjectOutputStream 对象的 writeObject(对象) 方法输出可序列化对象。注意写出一次,操作flush()

创建一个 ObjectInputStream
调用 readObject() 方法读取流中的对象
强调:如果某个类的字段不是基本数据类型或 String 类型,而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的 Field 的类也不能序列化

java">import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 序列化与反序列化
 * 注意:对象的序列化与反序列化使用的类要严格一致,包名,类名,类机构等等所有都要一致
 * @author
 *
 */
public class Test5 {
	public static void main(String[] args) {
		try {
//			Test5.testSerialize();
			Test5.testDeserialize();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 对象的序列化
	 */
	public static void testSerialize() throws Exception{
		//定义对象的输出流,把对象的序列化之后的流放到指定的文件中
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:/tt.txt"));
		
		Person p = new Person();
		p.name = "zhangsan";
		p.age = 11;
		
		out.writeObject(p);
		out.flush();//刷写数据到硬盘
		
		out.close();
	}
	
	/**
	 * 对象的反序列化
	 */
	public static void testDeserialize() throws Exception{
		//创建对象输入流对象,从指定的文件中把对象序列化后的流读取出来
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/testdemo/demo/src/day13/tt9.txt"));
		
		Object obj = in.readObject();//in.readObject()返回的是object对象
		
		Person p = (Person)obj;//强制转换类型
		System.out.println(p.name);
		System.out.println(p.age);
		
		in.close();
		
	}
}

5.RandomAccessFile 类

//RandomAccessFile的构造有两个参数,参数1是读写的文件的路径
//参数2是指定 RandomAccessFile 的访问模式
//r: 以只读方式打开
//rw:打开以便读取和写入
//rwd:打开以便读取和写入;同步文件内容的更新
//rws:打开以便读取和写入;同步文件内容和元数据的更新
//最常用是r和rw

随机读

java">import java.io.RandomAccessFile;

public class Test4 {
	public static void main(String[] args) {
		try {
			Test4.testRandomAcessFileRead();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void testRandomAcessFileRead() throws Exception {
		RandomAccessFile raf = new RandomAccessFile("D:\\tt.txt","r");
		raf.seek(8);//通过设置读取文件内容的起始点,来达到从文件的任意位置读取
		
		byte[] b = new byte[1024];
		int len = 0;
		
		while((len = raf.read(b)) != -1) {
			System.out.println(new String(b, 0, len));
		}
		
		raf.close();
	
	
	
	}

}

随机写

// ra.seek(0);//设置写的起始点,0代表从开头写
//注意:如果是在文件开头或者中间的某个位置开始写的话,就会用写的内容覆盖掉等长度的原内容
ra.length()代表从文件的最后结尾写,也就是文件的追加

java">/**
	 * 随机写
	 */
	public static void testRandomAccessFileWrite() throws Exception{
		RandomAccessFile ra = new RandomAccessFile("D:\\Program Files\\eclipse-workspace\\demo\\src\\day13\\tt.txt", "rw");
		

		ra.seek(ra.length());//设置写的起始点,ra.length()代表从文件的最后结尾写,也就是文件的追加
		
		ra.write("你好".getBytes());
		
		ra.close();
	}

总结:
流是用来处理数据的。

处理数据时,一定要先明确数据源,与数据目的地
数据源可以是文件,可以是键盘。
数据目的地可以是文件、显示器或者其他设备。

而流只是在帮助数据进行传输,并对传输的数据进行处理,比如过滤处理、转换处理等。

KEEP ON GOING NEVER GIVE UP!


http://www.niftyadmin.cn/n/1707591.html

相关文章

夸克浏览器_关于夸克的思考

夸克浏览器Quarkus,新的“超音速,亚原子” Java框架目前正受到广泛关注。 对于企业Java的未来而言,此构建和运行时工具背后的思想确实比我们感兴趣。 使用Quarkus有什么好处和缺点? 摆脱动力 Quarkus认为,在容器化的世…

教你一招:低代码开发平台实现抗疫物资管理系统的搭建

2019年末发生了全球性的公共卫生——新冠疫情,这次疫情给人类的生活带来了巨大的影响与威胁。纵观全球疫情,中国因其防控得当让疫情获得了很好都得控制,避免了大规模蔓延带来的伤害。经过近两年的“防疫之战”,全国上下都知道了疫…

5步带你完成TensorFlow的安装(CPU下win10)

Step1: 安装anaconda(下载好傻瓜式安装即可)官网网址:https://www.anaconda.com/ 下载地址(清华映像站): https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ Step2: 打开Anaconda Prompt窗口&#…

selenium_Selenium WebDriver中的TestNG侦听器及示例

seleniumJava提供了不同的接口,使您可以修改TestNG行为。 这些接口在Selenium WebDriver中进一步称为TestNG侦听器。 TestNG Listeners还允许您根据项目需求自定义测试日志或报告。Selenium WebDriver中的TestNG侦听器是侦听某些事件并跟踪测试执行情况的模块&#…

浅析低代码开发平台的市场现状与趋势

伴随着互联网技术持续发展趋势,数字化转型早就变成企业发展趋势的新机遇。做为企业数字化转型的关键专用工具、联接日常日常生活与世界经济的新根基,软件看起来至关重要。殊不知,传统式软件开发必须代码,时间长、成本增加、迭代更…

Java学习笔记21(线程)

创建线程的方式 继承Thread类 定义子类继承Thread类。子类中重写Thread类中的run方法。创建Thread子类对象,即创建了线程对象。调用线程对象start方法:启动线程,调用run方法。 run(),想要开启多线程中运行代码逻辑,就写到run&am…

java抽象类扩展_用Java中的抽象类扩展抽象类

java抽象类扩展示例问题 当我创建Java :: Geci抽象类AbstractFieldsGenerator和AbstractFilteredFieldsGenerator我遇到了一个不太复杂的设计问题。 我想强调一下,对于某些人来说,这个问题和设计可能看起来很明显,但是在我最近与一位初级开发…

JavaSE自学笔记总结

文章目录前言00零基础内容01基础程序设计部分:02面向对象编程03Java新特性04应用程序开发前言 学了Java基础部分大概一个月,基本概念语法学完了,看了一下,距离上一篇博客有10天了,前几天偷懒了,没及时总结…