超牛牪犇Java之IO流(后篇)字节流&字符流&转换流&缓冲流

本文详细介绍Java中文件操作的方法,包括字节流与字符流的基本使用、文件复制、转换流及缓冲流的应用技巧,并提供实际代码示例。

一.字节流

文件的续写:

利用构造方法的参数进行续写(布尔参数)

true 表示续写

FileOutputStream fos = new FileOutputStream(file, true);
fos.write("hello\n".getBytes());
fos.write("TaylorSwift\n".getBytes());

mac的换行是加 "\n"

windows的换行是加 "\r\n"

exercise1:

使用字节流 进行文件的复制(需要异常处理 并计算两种读写方式的时间)

对文件进行读写(一边读一边写)

long start = System.currentTimeMillis();
File file1 = new File("/Users/Commander/Desktop/test/123.doc");
File file2 = new File("/Users/Commander/Desktop/test/321.doc");
FileInputStream fis = null;
FileOutputStream fos = null;
try {
	fis = new FileInputStream(file1);
	fos = new FileOutputStream(file2);
	int len = 0;
	byte[] bs = new byte[1024];
	while ((len = fis.read()) != -1) {
		fos.write(bs, 0, len);
	}			
} catch (FileNotFoundException e) {
	throw new RuntimeException("文件找不到");
} catch (IOException e) {
	throw new RuntimeException("读写失败");
} finally {
	// 进行流的关闭 先关哪个都行()已经读写完毕
	if (fis != null) {
		try {
			fis.close();
		} catch (IOException e) {
			throw new RuntimeException("关闭失败");
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭失败");
				}
			}
		}
	}
}
long stop = System.currentTimeMillis();
System.out.println(stop - start);

exercise2:

将一个文件夹复制到另一个文件夹下

提示:

需要两个参数:

1.(源文件) 要被复制的文件

2.目标文件 复制到哪个文件夹下

	public static void getFile(File file1,File file2) throws IOException {
		//新文件夹的名字是源文件的名字
		//路径是目标文件的路径
		File newFile = new File(file2,file1.getName());
		newFile.mkdir();
		File[] listFiles = file1.listFiles();
		
		for (File file : listFiles) {
				if (file.isFile()) {
					//复制文件
					int num = 0;
					byte[] bs = new byte[1024];
					FileInputStream fis = new FileInputStream(file);
					//创建一个要写入的文件(拼接文件名字)
					File tempFile = new File(newFile,file.getName());
					FileOutputStream fos = new FileOutputStream(tempFile);
				while ((num = fis.read()) != -1) {
					fos.write(bs,0,num);
				}	
				fis.close();
				fos.close();
			}else {
				//文件夹 继续遍历
				getFile(file, newFile);
			}
		}
	}

exercise3:

将一个文件夹下的所有txt文件 复制到另一个文件夹下并且保存为.java文件

先写个过滤器 获取txt文件

class getTxt implements FileFilter {
        @Override
	public boolean accept(File pathname) {
		if (pathname.isDirectory()) {
			return true;
		}
		return pathname.getName().endsWith("txt");
	}	
}

写方法:

	public static void copyTxt(File src,File dest) throws IOException {
		// 遍历源文件
		//File newFile = new File(dest, src.getName());
		File[] files = src.listFiles(new getTxt());
		for (File subFile : files) {
			if (subFile.isFile()) {
				FileInputStream fis = new FileInputStream(subFile);
				// 构建写的路径
				String name = subFile.getName();
				String[] split = name.split("\\.");
				// 构建写入的文件
				File temp = new File(dest, split[0]+".java");
				FileOutputStream fos = new FileOutputStream(temp);  // 创建写的输出流
				// 读
				int len = 0;
				byte[] b = new byte[1024];
				while ((len = fis.read(b)) != -1) {
					fos.write(b, 0, len);
				}
				fis.close();
				fos.close();		
			} else {
				// 继续遍历
				copyTxt(subFile, dest);
			}
		}
	}

基本的编码格式:

mac默认使用UTF-8格式(通用编码格式)

一个中文字符 占三个字节

windows GBK格式(简体中文格式)

一个中文字符 占两个字节

二.字符流

writer(写文件) 字符输出流

reader(读文件) 字符输入流

是所有字符流的父类(抽象类)

一些方法:

//创建一个文件字符输出流
File file = new File("/Users/Commander/Desktop/test/taylor.txt");
FileWriter fw = new FileWriter(file);
//写
fw.write(65);
//刷新
//相当于写入的时候有一个缓冲区
//写的字符实际上是先写入到缓冲区
//刷新的时候才会将写的字符全部写入到文件中
//建议:写一次刷新一次
fw.flush();
//利用字符数组写入
char[] c = {'a','b','c','d'};
fw.write(c);
fw.flush();
//用字符串写入
fw.write("身无彩凤双飞翼\n");
fw.write("心有灵犀一点通\n");
fw.flush();
//关闭流资源
//关闭流资源之前 会自动刷新缓冲区
fw.close();

exercise:

利用字符流 复制文件(带异常处理)

字符流 只支持文档类

FileReader fr = null;
FileWriter fw = null;
try {
	fr = new FileReader("/Users/Commander/Desktop/test/taylor.txt");
	fw = new FileWriter("/Users/Commander/Desktop/test/swift.txt");
	//读写
	int len = 0;
	char[] c = new char[1024];
	while ((len = fr.read(c)) != -1) {
		//写
		fw.write(c, 0, len);
		//刷新
		fw.flush();
	}
} catch (FileNotFoundException e) {
	throw new RuntimeException("文件找不到");
} catch (IOException e) {
	throw new RuntimeException("读写失败");
}
finally {
	if (fr != null) {
		try {
			fr.close();
		} catch (IOException e) {
			throw new RuntimeException("关闭失败");
		}finally {
			if (fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					throw new RuntimeException("关闭失败");
				}
			}
		}
	}
}

三.转换流

 转换流

 OutputStreamWrite(字符流通向字节流的桥梁)

 1.程序中写入字符时 先使用转换流 根据转换流想查询的码表格式去查询

 2.如果查的是GBK的格式 那么一个中文字符就查到了两个字节的字节编码

 3.这个字节编码最后给到了构建转换流时 传入的字节流

 4.通过这个字节流 按字节写入到文件中

 转换流:可以查询对应的编码表

 

 转换流可以根据你想要的编码格式进行读写

 读写时可以设置编码格式

 

 构造方法(不传编码格式 默认使用的是系统的编码格式)

 1.需要字节输出流

 2.编码格式的名字(UTF-8,GBK  不区分大小写)

 

 InputStreamReader (读取文件 字节流通向字符流的桥梁)

 1.按字节读取文件 将字节编码给到转换流

 2.如果是UTF-8需要三个字节

 3.使用字符流读取到程序中


按操作系统默认格式写一个文件:

public static void getUTF8() throws IOException {
        //创建一个字节输出流
	FileOutputStream fos = new FileOutputStream("/Users/Commander/Desktop/test/UTF8.txt");
	//创建一个转换流
	OutputStreamWriter osw = new OutputStreamWriter(fos);
	//写文件
	osw.write("Taylor");
	//注意:
	//1.一般只关外层的流
	//2.自己创建的流自己关 获取系统的流不用管
	osw.close();
}

按GBK格式写入文件:

public static void getGBK() throws IOException {
	FileOutputStream fos = new FileOutputStream("/Users/Commander/Desktop/test/GBK.txt");
	OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
	osw.write("Taylor");
	osw.close();
}

按默认的UTF-8格式读文件:

public static void readByUTF8() throws IOException {
	FileInputStream fis = new FileInputStream("/Users/Commander/Desktop/test/UTF8.txt");
	InputStreamReader isr = new InputStreamReader(fis);
	int num = 0;
	char[] c = new char[1024];
	while ((num = isr.read(c)) != -1) {
		System.out.println(new String(c, 0, num));
	}
	isr.close();
}

按GBK格式读文件:

public static void readByGBK() throws IOException {
	FileInputStream fis = new FileInputStream("/Users/Commander/Desktop/test/GBK.txt");
	InputStreamReader isr = new InputStreamReader(fis,"GBK");
	int num = 0;
	char[] c = new char[1024];
	while ((num = isr.read(c)) != -1) {
		System.out.println(new String(c, 0, num));
	}
	isr.close();
}

四.缓冲流

流:就是用来读写文件的  所以就牵扯到了效率的问题

缓冲流(高效流)

  内部自带了一个缓冲区(字节数组)

  BufferedOutputStream(写文件)  缓冲字节输出流

  BufferedInputStream(读文件)  缓冲字节输入流

  

  测试缓冲流的高效

  读取同一个大文件 查看读取的时间

  模板设计模式

  1.字节输入流

   一个字节一个字节读

   使用缓冲数组来读

  2.缓冲字节输入流









评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值