字符流,缓冲字符流(各种复制文件,文件夹),集合与文件,序列化与反序列化

本文深入讲解Java中的IO流操作,包括字节流、字符流及其缓冲机制,演示如何使用缓冲流进行高效的数据读写,同时介绍了字符流的使用方法及序列化与反序列化的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

缓冲字节流的数据读写过程

读数据是从缓冲区中读取数据

文件→缓冲区→自定义容器

写出的数据是放在缓冲区里面,如果需要将数据刷新到硬盘上面去,需要调用flush方法。(否则只有当缓冲区填满的时候才会将数据写写出来)

public class Demo {
	public static void main(String[] args) {
		BufferedInputStream bis=null;
		BufferedOutputStream bos=null;
		try {
			FileInputStream fis= new FileInputStream("/Users/yoofale/Desktop/haha.txt");
			bis = new BufferedInputStream(fis);
			FileOutputStream fos= new FileOutputStream("/Users/yoofale/Desktop/666.txt");
			bos = new BufferedOutputStream(fos);
			byte[] buf=new byte[1024];
			int len=-1;
			while((len=bis.read(buf))!=-1){
				bos.write(buf,0,len);
//				写一次数据就刷新一次数据
				bos.flush();
			}
			System.out.println("拷贝成功");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(bos!=null){
				try {
					bos.close();//close内部会自动调用flush方法
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(bis!=null){
				try {
					bis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
}

依旧是复制文件标准套路,拷贝文件夹要用递归。

 

 

 

字符流:因为使用字节流操作文本数据比较麻烦,所以出现了字符流

字符流=字节流+编码表

编码表:就是一张可以表示文字的码表。

 

转换流:

OutputStreamWriter 字符流通向字节流的桥梁

InputStreamReader 字节流通向字符流的桥梁

 

字符流写出

	public static void main(String[] args) throws Exception {
		FileOutputStream fos = new FileOutputStream("/Users/yoofale/Desktop/haha.txt");
		OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
		osw.write("大吉大利,今晚吃鸡");
		osw.flush();
		osw.close();
	}

 

 

 

字符流读取

public static void main(String[] args) throws Exception {
public InputStreamReader(InputStream in)创建一个使用默认字符集的InputStreamReader
		FileInputStream fis = new FileInputStream("/Users/yoofale/Desktop/haha.txt");
//		public InputStreamReader(InputStream in,String charsetName)创建使用指定字符集的InputStreamReader
		InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
//		public int read(char[] cbuf)将字符读入数组,读取的字符数,如果已经到达流的末尾,返回-1
//		定义一个变量用于统计读取的字符的个数
		char[] cbuf=new char[1024];
		int len =isr.read(cbuf);
//		将字符数组转换成字符串
		String content = new String(cbuf,0,len);
		System.out.println(content);
	}

模式等同于字节流。读取后放入缓冲区,进行计数,多了一步将字符数组转化成字符串的过程

 

 

 

转换流的简化写法

FileWriter是OutputStreamWriter的简化写法,FileWriter的编码方式就是默认的平台编码(写入字符文件的便捷类)

FileReader是InputStreamReader的简化写法,FileReader的编码方式也是默认的平台编码

 

简化的写入

public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		FileWriter fw =new FileWriter("/Users/yoofale/Desktop/mm.txt");
		fw.write("简化版成功写入");
		fw.flush();
		fw.close();
	}

简化的读取

public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		FileReader fr = new FileReader("/Users/yoofale/Desktop/mm.txt");
		char[] brr=new char[1024];
		int len =fr.read(brr);
		System.out.println(new String(brr, 0, len));
			
	}

写入结束一定要刷新,关闭流。

读取一定要用缓冲区,定义变量。

 

简化版的复制文件

public class CopyTestQuickly {

	private static FileReader fr;

	public static void main(String[] args) throws Exception {
		fr = new FileReader("/Users/yoofale/Desktop/haha.txt");
		FileWriter fw = new FileWriter("/Users/yoofale/Desktop/hehe.txt");
		char[] ass =new char[1024];
		int len =-1;
		while((len=fr.read(ass))!=-1){
			fw.write(ass,0,len);
		}
		fw.close();
		fr.close();
		System.out.println("拷贝成功");
	}

}

 

 

 

缓冲字符流

写入数据

public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		FileWriter fw = new FileWriter("/Users/yoofale/Desktop/haha.txt");
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write("西瓜皮");
		bw.append("6");//append是在后面写入
		bw.newLine();//nextLine()是换行
		bw.write("不知细叶谁裁出,二月春风似剪刀");
		bw.flush();
		bw.close();
	}

newLine换行

 

读取数据

public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		FileReader fr = new FileReader("/Users/yoofale/Desktop/haha.txt");
		BufferedReader br = new BufferedReader(fr);
		String line = br.readLine();
		System.out.println(line);
		line = br.readLine();
//		readLine()是读取一个文本行,没有数据了返回null
		System.out.println(line);
		line = br.readLine();
		System.out.println(line);
	}

 

 

关于使用缓冲拷贝和普通拷贝时间的区别,先System.currentTimeMillis(),再分别调用封装的拷贝文件类,再接收时间,求差值。比较差值即可比较出效率。

 

 

复制文本文件

使用缓冲区写出数据时,如果中途不着急将一部分数据刷新出去,就等到最后关闭流的时候顺带将数据刷出去   

如果缓冲区存满了,那么里面的数据都会强制刷新出去。

 

普通读取都是一次一个字符数组,很慢。写入可以一次一行。效率过低

缓冲字符流读取写入都很快,一次一行。!!!!!!!!!!!!切记newline换行

 

 

字符流缓冲最后都简化为BufferedReader BufferedWriter

字节流都是BufferedInputStream     BufferedOutputStream

 

将集合中的内容保存到文件中

public class ArrayListToFile {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		ArrayList<String> list = new ArrayList<String>();
		list.add("我");
		list.add("是");
		list.add("我");
		BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/yoofale/Desktop/haha.txt"));
		for (String content : list) {
			bw.write(content);
			bw.newLine();
		}
		bw.close();
		System.out.println("写出成功");
	}

}

 

 

 

将文件中的内容写入集合中

public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new FileReader("/Users/yoofale/Desktop/haha.txt"));
		ArrayList<String> list = new ArrayList<String>();
		String line=null;
		while((line=br.readLine())!=null){
			list.add(line);
		}
		br.close();
		for (String content : list) {
			System.out.println(content);
		}
	}

 

拷贝单级文件

public class CopyFolderDemo {

	public static void main(String[] args) {
//		1.封装原文件夹的文件对象
		File srcFolder = new File("/Users/yoofale/Desktop/666");
//		2.封装要拷贝到的文件夹对象
		File destFolder = new File("/Users/yoofale/Desktop/777");
//		3.在目标位置创建一个一模一样的文件夹
		destFolder =new File(destFolder,srcFolder.getName());
		destFolder.mkdir();
//		4.获取原文件夹中所有的子文件对象
		File[] files = srcFolder.listFiles();
//		5.遍历所有的子文件对象数组,然后拷贝到目标文件夹中
		for (File srcFile : files) {
//			在目标文件夹里面创建一个名字一模一样的文件
			File destFile = new File(destFolder,srcFile.getName());
//			调用拷贝文件的方法
			copyFile(srcFile,destFile);
		}
		System.out.println("拷贝成功");
	}

	private static void copyFile(File srcFile, File destFile) {
		try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
				BufferedOutputStream bos =new BufferedOutputStream(new FileOutputStream(destFile))){
			byte[] buf= new byte[1024];
			int len =-1;
			while((len=bis.read(buf))!=-1){
				bos.write(buf,0,len);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

 

 

 

 

java序列化:把Java对象转换成字节序列的过程

Java反序列化:把字节序列恢复为Java对象的过程

当两个java进程进行通信的时候,发送方需要进行java序列化,接收方需要进行java反序列化

 

序列化

// 被序列化的对象必须实现Serializable接口,否则运行错误
	public static void main(String[] args) throws Exception {
		// public objectOutputStream(OutputStream
		// out)创建写入指定OutputStream的ObjectOutputStream
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/yoofale/Desktop/person.txt"));
		// 将对象写出到文件中
		// public final void writeobject(Object obj)将指定对象写入ObjectOutputStream
		oos.writeObject(new Person("张三", 17));
		oos.close();
	}

要序列化的类一定要实现Serializable接口

一个成员如果被transient修饰,那么这个对象不能序列化保存。

 

反序列化

private static void fileToObject() throws Exception {
		// TODO Auto-generated method stub
		ObjectInputStream ois=new ObjectInputStream(new FileInputStream("/Users/yoofale/Desktop/person.txt"));
		Object obj = ois.readObject();
		System.out.println(obj);
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值