折纸的不归路(22)

一.线程补充内容

达到线程同步的条件的步骤

1.确认谁是共享数据,synchronized要锁住谁
2.锁住谁就执行谁的wait()和notify()
3.提供boolean的旗标,来判断什么时候开始等待,什么时候不需要等待

锁的释放问题

什么时候锁会释放
1.临界区代码执行完毕(使用notify不会立即释放锁,也会等待临界区代码执行完毕)
2.临界区代码执行过程中遇到error或者exception
3.临界区代码执行过程中出现return,break
4.调用wait方法,立即释放锁
什么时候锁不释放
sleep
yeild

二.I/O流

数据流向

以程序作为媒介
把程序得到的数据发送到某些位置上(控制台,文件,网络)
可以把外部(网络,文件)的数据传输到程序中

流的分类

1.根据数据的流向
输入流和输出流
2.根据数据的类型
字节流和字符流

java中流是什么

流就是一个对象
JDK种提供了很多流的类
一些类是以InputStream和OutputStream结尾的
一些类是以Writer和Reader结尾的
字节输入流(InputStream),字节输出流(OutputStream)
字符输入流(Reader),字符输出流(Writer)

一些实例

1.InputStream,OutputStream

输入流提供了读的方法
read();//一个字节一个字节读
read(byte[] b);
read(byte[] b , int off , int len)//
输出流提供了写的方法
write(int i);//写出对应的字节
write(byte[] b);//写出对应的字节数组
write(byte[] b, int off , int len);//

2.FileInputStream,FileOutputStream

文件流,字节流
总结了一下使用流的步骤
1.根据业务逻辑确定要使用什么流
2.选择好流之后对流进行初始化
3.使用读取方法read和写入方法write进行操作
4.使用完毕之后记得手动关闭流的资源
实例:用流实现文件的拷贝

/**
 * 使用流进行文件拷贝 从在桌面上拷贝一个文件到工作空间中
 * 
 * @author Acer
 *
 */
public class FileCopy {
	public static void main(String[] args) {
		// 第一步,选择使用那个流
		FileInputStream fis = null;// 输入流
		FileOutputStream fos = null;// 输出流
		// 对流进行初始化
		try {
			//传递要读取的文件位置
			fis = new FileInputStream("C:/Users/Acer/Desktop/01.jpg");
			//传递文件输出的位置
			fos = new FileOutputStream("D:/copy.jpg");
			//第三步:读取文件
			System.out.println("文件开始读取");
			int len = 0;
			//定义一个字节数组的缓冲区
			byte[] b = new byte[1024];
			while((len = fis.read(b))!=-1) {
				//当len=-1的时候,代表文件到达末尾,跳出循环
				//当i!=-1的时候证明读到了字节,需要写出去
//				System.out.println(new String(b));
//				fos.write(len);
				fos.write(b);
			}
			System.out.println("文件输出完毕");
			//第四步:使用完流之后记得关闭资源
			//记住开几个关几个,可以使用finally代码块
			fos.close();
			fis.close();
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			
				try {
					if(fos!=null) fos.close();
					if(fis!=null) fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
		}

	}
}

因为要多次执行资源关闭的操作,所以对资源关闭进行了封装,后面的测试都直接使用了封装的方法.

/**
 * 封装一下关闭资源的方法
 * 成对的关闭字节输入流和字节输出流 in 字节输入流 out 字节输出流
 * @author Acer
 *
 */
public class CloseUtil {
	public static void closeStream(InputStream in, OutputStream out) {

		try {
			if (in != null)
				in.close();
			if (out != null)
				out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

3.BufferedInputStream,BufferedOutputStream

缓冲流,字节流,包装流
主要用来提升效率的
注意谁是基础流,谁是包装流
read(byte[]);读取一个byte数组
write(byte[],off,len)这个len是实际读到的字节数
没有必要把byte数组的长度全部读出来,会造成多读
缓冲流相关测试:

/**
 * 缓冲流测试
 * 
 * @author Acer
 *
 */
public class BufferTest {
	public static void main(String[] args) {
		// 1.先确认要使用什么流
		// 需要使用包装流,需要使用对应的文件流
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		FileInputStream fis = null;
		FileOutputStream fos = null;
		// 对四个流进行初始化
		// 需要读取的文件名字
		
		try {
			String inPath = "8.3.txt";// 必须是桌面有的文件,而且必须带后缀
			fis = new FileInputStream(new File(UrlFiled.DESKTOP + inPath));
			// 需要写入的文件名字,如果文件不存在,则自动创建
			String outPath = "new.txt";
			fos = new FileOutputStream(new File(UrlFiled.PROJECT + outPath));

			bis = new BufferedInputStream(fis);
			bos = new BufferedOutputStream(fos);

			// 读取资源并写出
			byte[] b = new byte[8];
			int len = -1;

			while ((len = bis.read(b)) != -1) {
				System.out.println(len);
				bos.write(b, 0, len);
				bos.flush();// 清空一下缓冲区
			}
			
			
			System.out.println("资源写出完毕...");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			//关闭资源,使用封装的方法
			CloseUtil.closeStream(bis, bos);
			CloseUtil.closeStream(fis, fos);

		}
	}
}

4.DataInputStream,DataOutputStream

字节流,包装流,数据流
读写java中的基本数据类型的
一般不会直接从文件中读取
作为一个数据的持久化来做的,一般做法,把基本数据类型保存到文件中作为
持久化的一个方式,然后等到需要的时候再从文件中取出来
测试基本数据类型的存取:

/**
 * 测试基本数据类型的存取
 * 
 * @author Acer
 *
 */
public class DataTest {
	public static void main(String[] args) {
		DataInputStream dis = null;
		DataOutputStream dos = null;
		FileInputStream fis = null;
		FileOutputStream fos = null;

		// 先写入
		try {
			// fos = new FileOutputStream(UrlFiled.PROJECT+"data.txt");
			// //
			// dos = new DataOutputStream(fos);
			// System.out.println("开始输入数据");
			// //不需要使用循环写入,直接写
			// dos.writeInt(20);//写入文件一个int类型的数据
			// dos.writeLong(30L);//写入文件一个long类型的数据
			// dos.writeBoolean(true);
			// dos.writeDouble(10.0);
			// dos.writeChar(97);
			// dos.writeFloat(40.0f);
			// System.out.println("输出数据完毕,请查看指定位置...");

			// 开始读取曾经保存的数据类型
			fis = new FileInputStream(UrlFiled.PROJECT + "data.txt");
			dis = new DataInputStream(fis);
			// 直接开始读
			System.out.println("开始读取数据");// 读取时必须按写入的顺序来进行读取
			System.out.println("读取到的int数据" + dis.readInt());
			System.out.println("读取到的long数据" + dis.readLong());
			System.out.println("读取到的boolean数据" + dis.readBoolean());
			System.out.println("读取到的double数据" + dis.readDouble());
			System.out.println("读取到的char数据" + dis.readChar());
			System.out.println("读取到的float数据" + dis.readFloat());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			CloseUtil.closeStream(dis, dos);
			CloseUtil.closeStream(fis, fos);
		}

	}
}

5.ObjectInputStream,ObjectOutputStream

字节流
读写对象类型的数据
向文件中写入一个对象保存
从文件中读出一个对象保存
保存对象测试:

/**
 * 测试保存一个对象到文件里 以字节的形式保存一个对象
 * 
 * @author Acer
 *
 */
public class ObjectTest {
	public static void main(String[] args) {
		ObjectOutputStream oos = null;
		FileOutputStream fos  =null;
		try {
			File objectfile = new File(UrlFiled.PROJECT+"obj");
			fos = new FileOutputStream(objectfile);
			oos = new ObjectOutputStream(fos);
			//往文件中写入一个对象
			Student stu = new Student("tom", 22, "男");
//			oos.writeObject("今天中午该吃饭了");//String实现过序列化
			System.out.println("开始写入对象");
			oos.writeObject(stu);
			System.out.println("写入对象成功");
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			CloseUtil.closeStream(null, oos);
			CloseUtil.closeStream(null, fos);
		}
		
	}
}

序列化和反序列化

序列化:该对象具有能够变成字节的权利,可以通过字节流保存到文件里
反序列化:可以从文件中读取并且通过字节序列构建成一个对象

如何让对象实现序列化

java.io.Serializable 接口
让该对象的类实现序列化接口

三.心得

今天学的内容主要是关于i/o的api,以及对一些方法的应用,都不是很难的东西,重要的还是多写代码,明天加油!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值