Java基础——Day21——缓冲流,序列化,对象流,过滤器,初识线程

Day 21(掌握)

一、缓冲流

  • 我们的内存是很大的,频繁的读写会造成资源的浪费
  • 可以采取读很多次,内容差不多大的时候,一次将多从读取的内容写出去
  • 缓冲流分为字符缓冲流和字节缓冲流

二、字节缓冲输入流

2.1 定义

  • BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 markreset 方法的能力。

2.2 创建对象

BufferedInputStream(InputStream in) 
          创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 
BufferedInputStream(InputStream in, int size) 
          创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 

三、字节缓冲输出流

3.1 定义

  • 该类实现缓冲的输出流。
  • 通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

3.2 创建对象

BufferedOutputStream(OutputStream out) 
          创建一个新的缓冲输出流,以将数据写入指定的底层输出流。 
BufferedOutputStream(OutputStream out, int size) 
          创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。 

3.3 读写案例

package com.qf.buffer;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo01 {
	public static void main(String[] args) {
		/**
		 * 	BufferedInputStream(InputStream in) 
			          创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 
			BufferedInputStream(InputStream in, int size) 
			          创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 
			          
			          
			BufferedOutputStream(OutputStream out) 
			          创建一个新的缓冲输出流,以将数据写入指定的底层输出流。 
			BufferedOutputStream(OutputStream out, int size) 
			          创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。 

		 */
		
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(new FileInputStream(new File("D:\\files\\JavaFiles\\Java2005\\day21\\img03.jpg")));
			bos = new BufferedOutputStream(new FileOutputStream(new File("D:\\files\\JavaFiles\\Java2005\\day21\\img03-副本.jpg")));
			
			// 读写数据
			byte[] arrB = new byte[1024*8];
			int len = -1;
			
			while((len = bis.read(arrB)) != -1) {
				bos.write(arrB, 0, len);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭流
				bos.close();
				bis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

3.4 缓冲流和字节流速度比较

字节流复制视频文件
package com.qf.buffer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo02 {
	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		
		
		FileInputStream fis = null;
		FileOutputStream fos = null;
		
		try {
			fis = new FileInputStream(new File("D:\\迅雷下载\\快手枪手快枪手.mp4"));
			fos = new FileOutputStream(new File("D:\\迅雷下载\\快手枪手快枪手-字节流.mp4"));
			
			// 读写数据
			byte[] arrB = new byte[1024*8];
			int len = -1;
			
			while ((len = fis.read(arrB)) != -1) {
					fos.write(arrB, 0, len);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fos.close();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		long endTime = System.currentTimeMillis();
		System.out.println("文件复制完成...耗时:" + (endTime-startTime));
		// 18972
	}
}

缓冲流复制文件
package com.qf.buffer;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo03 {
	public static void main(String[] args) {
		// 开始的时间
		long startTime = System.currentTimeMillis();
		
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(new FileInputStream(new File("D:\\迅雷下载\\快手枪手快枪手.mp4")));
			bos = new BufferedOutputStream(new FileOutputStream(new File("D:\\迅雷下载\\快手枪手快枪手-缓冲流.mp4")));
			
			// 读写数据
			byte[] arrB = new byte[1024*8];
			int len = -1;
			
			while((len = bis.read(arrB)) != -1) {
				bos.write(arrB, 0, len);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭流
				bos.close();
				bis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		long endTime = System.currentTimeMillis();
		System.out.println("文件复制完成...耗时:" + (endTime-startTime));
	}
}

四、字符缓冲输入流

4.1 定义

  • 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
  • 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
  • 通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。

4.2 创建对象

BufferedReader(Reader in) 
          创建一个使用默认大小输入缓冲区的缓冲字符输入流。 
BufferedReader(Reader in, int sz) 
          创建一个使用指定大小输入缓冲区的缓冲字符输入流。 

五、字符缓冲输出流

5.1 定义

  • 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
  • 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
  • 该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义
  • 并非所有平台都使用新行符 (’\n’) 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。
  • 通常 Writer 将其输出立即发送到底层字符或字节流。

5.2 创建对象

BufferedWriter(Writer out) 
          创建一个使用默认大小输出缓冲区的缓冲字符输出流。 
BufferedWriter(Writer out, int sz) 
          创建一个使用给定大小输出缓冲区的新缓冲字符输出流。 

5.3 字符缓冲流案例

package com.qf.buffer;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo04 {
	public static void main(String[] args) {
		/**
		 * 	BufferedReader(Reader in) 
			          创建一个使用默认大小输入缓冲区的缓冲字符输入流。 
			BufferedReader(Reader in, int sz) 
			          创建一个使用指定大小输入缓冲区的缓冲字符输入流。 

		 * 	BufferedWriter(Writer out) 
			          创建一个使用默认大小输出缓冲区的缓冲字符输出流。 
			BufferedWriter(Writer out, int sz) 
			          创建一个使用给定大小输出缓冲区的新缓冲字符输出流。 
		 */
		// 声明字符缓冲流对象
		BufferedReader br = null;
		BufferedWriter bw = null;
		
		try {
			// 实例化
			br = new BufferedReader(new FileReader(new File("D:\\files\\JavaFiles\\Java2005\\day21\\threeCountry.txt")));
			bw = new BufferedWriter(new FileWriter(new File("D:\\files\\JavaFiles\\Java2005\\day21\\threeCountry-副本.txt")));
			
			// 读写数据
			char[] arrC = new char[1024*8];
			int len = -1;
			
			while ((len = br.read(arrC)) != -1) {
				bw.write(arrC, 0, len);
			}
			// 读取结束,写入不知道是否结束,强制写入
			bw.flush();
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭流
				bw.close();
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("文件复制完成...");
	}
}

六、序列化

  • 传送阵
    • 传送的过程中需要记录对象的每一个分子的编号,序号
  • 网络传输
    • 可能会传输对象,对象以字节流的方式传输
    • 接收到对象后还要重组,需要反序列化
  • 实现一个接口
    • Serializable
package com.qf.seri;

import java.io.Serializable;

public class Stu implements Serializable{

	/**
	 * 序列化的id
	 * 传送和接收遵照相同的规则
	 */
	private static final long serialVersionUID = 112233445566778899L;
	
	
	// 属性
	String name;
	int age;
	
	public Stu() {
		super();
	}

	public Stu(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	// 方法
	public void show() {
		System.out.println("我是" + name);
	}

	@Override
	public String toString() {
		return "Stu [name=" + name + ", age=" + age + "]";
	}
}

七、对象输入流

7.1 定义

  • ObjectInputStream
  • ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
  • ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。

7.2 创建对象

ObjectInputStream(InputStream in) 
          创建从指定 InputStream 读取的 ObjectInputStream。

7.3 对象读取案例

package com.qf.seri;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Demo02 {
	public static void main(String[] args) {
		// 声明对象输入流
		ObjectInputStream ois = null;
		
		try {
			// 实例化对象输入流
			ois = new ObjectInputStream(new FileInputStream(new File("zhangsan.temp")));
			
			// 读取对象
			Object obj = ois.readObject();
			
			// 把读取到的内容转回原来的类型
			Stu stu = (Stu) obj;
			System.out.println(obj);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("对象读取完成...");
	}
}

八、对象输出流

8.1 定义

  • ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。
  • 可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。
  • 如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
  • 只能将支持 java.io.Serializable 接口的对象写入流中。
  • 每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。

8.2 创建对象

ObjectOutputStream(OutputStream out) 
          创建写入指定 OutputStream 的 ObjectOutputStream。

8.3 写入对象案例

package com.qf.seri;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Demo01 {
	public static void main(String[] args) {
		// 创建学生对象
		Stu stu = new Stu("zhangsan", 23);
		
		// 声明OOS
		ObjectOutputStream oos = null;
		try {
			// 实例化对象流
			oos = new ObjectOutputStream(new FileOutputStream(new File("zhangsan.temp")));
			
			// 把对象写入本地
			oos.writeObject(stu);
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("对象写入成功...");
	}
}

九、过滤器

9.1 定义

  • 筛选符合条件的文件
  • 需要实现FileFilter接口,重写accept方法

9.2 案例

package com.qf.filter;

import java.io.File;
import java.io.FileFilter;

public class Demo01 {
	public static void main(String[] args) {
		
		File file = new File("D:\\files\\JavaFiles\\Java2005\\day21");
		
		File[] listFiles = file.listFiles();
		for (File f : listFiles) {
			System.out.println("过滤之前的内容" + f);
		}
		
		System.out.println("=================================");
		System.out.println("=================================");
		TxtFilter tf = new TxtFilter();
		File[] listFiles2 = file.listFiles(tf);
		
		for (File f : listFiles2) {
			System.out.println("过滤之后获取到的内容:" + f);
		}
		System.out.println("=================================");
		
		File[] listFiles3 = file.listFiles(new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				String path = pathname.getAbsolutePath();
				return path.endsWith(".txt") ? true : false;
			}
		});
		
		for (File f : listFiles3) {
			System.out.println("过滤之后获取到的内容:" + f);
		}
	}
}

/**
 * 过滤所有TXT文件
 * @author Dushine2008
 *
 */
class TxtFilter implements FileFilter{

	@Override
	public boolean accept(File pathname) {
		String path = pathname.getAbsolutePath();
		if (path.endsWith(".txt")) {
			return true;
		}
		return false;
	}
}

9.3 练习

  • 输入一个文件夹,获取此文件夹中所有的.wmv文件–递归

Day 21笔记(下)

一、线程和进程(了解)

1.1 进程

  • 我们编写的代码、下载的引用,没运行的时候就是一堆文件
  • 这些代码、引用运行之后可以成为运行的程序,成为进程
  • 一个引用程序最少拥有一个进程

1.2 线程

  • 一个进程可能同时完成多项任务
  • 比如:网易云
    • 可以显示歌词
    • 可以播放视频
    • 可以播放音乐
    • 可以滚动进度条
    • 可以查看评论
  • 上述操作看起来可以同时进行的
  • 其实是有很多条线程在分别执行不同的工作
    • 有的线程播放视频
    • 有的线程播放音频
    • 有的线程驱动进度条变化
    • 。。。
  • 这些线程在CPU的额调度下交替执行,我们感觉不到。。。

二、Thread

2.1 定义

  • 线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
  • 每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。

2.2 创建对象的方式(掌握)

  • 继承Thread类
  • 创建这个子类的对象
  • 调用start方法
  • =========================
  • 实现Runnable接口
  • 创建实现类的对象,当做参数放入Thread构造方法中
  • 使用start启动线程

三、继承Thread类(掌握)

  • 创建一个Thread的子类
  • 创建Thread子类对象
  • 调用start方法
package com.qf.thread;

public class Demo01 {
	public static void main(String[] args) {
		// 创建子类的对象
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		
		// 开启线程:调用的start方法
		t1.start();
		t2.start();
		
		for (int i = 0; i < 100; i++) {
			System.out.println("main线程==========:" + i);
		}
		
		System.out.println("main线程运行结束...");
	}
}
/**
 * 继承Thread类,重写run方法
 * @author Dushine2008
 *
 */
class MyThread extends Thread{
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("子线程" + Thread.currentThread().getId() + ":"+i);
		}
	}
}

四、实现Runnable接口(掌握)

  • 编写实现类,实现Runnable接口
  • 重写run方法
  • 创建Runnable实现类的对象
  • 创建Thread对象,在构造方法中传入参数Runnable的实例
  • 调用start方法开启线程
package com.qf.thread;

public class Demo02 {
	public static void main(String[] args) {
		// 创建Runnable实现类对象
		MyRunnableThread r = new MyRunnableThread();
		// 创建Thread对象
		Thread t1 = new Thread(r,"线程01");
		Thread t2 = new Thread(r,"线程02");
		
		// 启动线程
		t1.start();
		t2.start();
		
		// 在主线程中输出0--100
		for (int i = 0; i < 100; i++) {
			System.out.println("main线程:" + i);
		}
		
		System.out.println("main线程运行结束...");
		
	}
}

/**
 * 编写实现类实现Runnable接口
 * 重写run方法
 * @author Dushine2008
 *
 */
class MyRunnableThread implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("子线程" + Thread.currentThread().getName() + ":" + i);
		}
	}
	
}

五、线程常用方法(掌握)

5.1 currentThread

  • 返回正在运行的当前线程对象
  • 包含线程名字、优先级、group等信息

5.2 getId

  • 返回当前线程的id
  • id是系统分配的id,是当前线程的唯一标识

5.3 getName

  • 获取当前线程的名字
  • 线程的名字可以通过构造方法传入,也可以通过setName方法设置

5.4 setName

  • 设置指定线程的名字

5.5 getPriority

  • 获取当前线程的优先级

5.6 setPriority

  • 设置线程的优先级
  • 优先级范围是1—10,默认优先级全部都是5
  • 数字越大,优先级越高,执行的几率就越高
package com.qf.thread;

public class Demo03 {
	public static void main(String[] args) {
		/**
		 * 	currentThread() 
          		返回对当前正在执行的线程对象的引用。
          	long getId() 
			          返回该线程的标识符。 
			String getName() 
			          返回该线程的名称。 
			int getPriority() 
			          返回线程的优先级。 
		 */
		
		MyRunnableThread02 r = new MyRunnableThread02();
		Thread t1 = new Thread(r, "线程01");
		Thread t2 = new Thread(r, "线程022222222222222");
		
		t1.setName("1号线程。。。。。。。。。。。。。");
		t1.setPriority(1);
		t2.setPriority(10);
		
		t1.start();
		t2.start();
		
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getId() + "===" + Thread.currentThread().getName() + "===" + i);
		}
		
		System.out.println(t1.getPriority() + "-------------------------------------------------");
		System.out.println(t2.getPriority() + "-------------------------------------------------");
		System.out.println(Thread.currentThread().getPriority() + "++++++++++++++++++++++++++++++++++++++++++++");
		
	}
}

class MyRunnableThread02 implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread() + ":" + i);
		}
	}
	
}

5.7 join

  • 插入–插队–优先执行
  • 插队的线程执行结束之后才会释放资源,其他的线程才能继续抢夺资源
package com.qf.thread;

public class Demo04 {
	public static void main(String[] args) {
		/**
		 * 	boolean isDaemon() 
			          测试该线程是否为守护线程。 
         	void join() 
          		等待该线程终止。 
          	void setDaemon(boolean on) 
          		将该线程标记为守护线程或用户线程。 
          	void setName(String name) 
          		改变线程名称,使之与参数 name 相同。 
           	void setPriority(int newPriority) 
          		更改线程的优先级。 
          	static void sleep(long millis) 
          		在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 
          	static void yield() 
          		暂停当前正在执行的线程对象,并执行其他线程。 
		 */
		
		MyRunnableThread04 r = new MyRunnableThread04();
		Thread t1 = new Thread(r, "子线程01");
		
		t1.start();
		
		// 主线程输出0---100
		for (int i = 0; i < 100; i++) {
			if (i == 20) {
				try {
					// main是普通用户,没有充值,先让普通用户体验20次,20次之后充值会员优先执行
					t1.join();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName() + "===" + i);
		}
	}
}

class MyRunnableThread04 implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread() + ":" + i);
		}
	}
	
}

5.8 setDaemon

  • 设置为守护线程
  • 其他的线程成为前台线程
  • 其他线程都执行结束后,守护线程自动结束,哪怕没有执行完内容也会终止
package com.qf.thread;

public class Demo05 {
	public static void main(String[] args) {
		MyRunnableThread05 r = new MyRunnableThread05();
		Thread t1 = new Thread(r, "子线程01");
		Thread t2 = new Thread(r, "子线程02");
		Thread t3 = new Thread(r, "子线程03");
		Thread t4 = new Thread(r, "守护线程04=================");
		
		t4.setDaemon(true);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		
		// 主线程输出0---100
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + "===" + i);
		}
	}
}
class MyRunnableThread05 implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread() + ":" + i);
		}
	}
}

5.9 yield

  • 礼让线程
  • 优先让其他线程执行,礼让不一定能成功
package com.qf.thread;

public class Demo06 {
	public static void main(String[] args) {
		MyRunnableThread06 r = new MyRunnableThread06();
		Thread t1 = new Thread(r, "子线程01");
		
		t1.start();
		
		for (int i = 0; i < 100; i++) {
			if (i % 10 == 0) {
				// main是普通用户,没有充值,每执行10次就要主动谦让一次
				Thread.yield();
			}
			System.out.println(Thread.currentThread().getName() + "===" + i);
		}
	}
}


class MyRunnableThread06 implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread() + ":" + i);
		}
	}
}

5.10 sleep

  • 线程休眠
package com.qf.thread;

public class Demo07 {
	public static void main(String[] args) {
		System.out.println("倒计时开始...");
		
		for (int i = 10; i >= 0; i--) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("火箭发射倒计时:" + i);
		}
		System.out.println("发射了...");
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值