JavaIO流、字符流的输入流、输出流(FileReader、BufferedReader、FileWriter、BufferedWriter)与两种文本文件的复制方法 Java第十五天(二)

IO流

  IO(Input/Output):输入和输出,指的是某个设备或环境进行数据的输入或输出,Java将输入、输出抽象成流对象来解决。
 例:以Java游戏程序为中心
在这里插入图片描述

IO流在Java中从输入输出角度分类IO流在Java中从数据的角度分类
输入流字符流 例:word文件、java文件
可以理解为文本,我们能直接能读懂的都可以认为是字符流
输出流字节流 例:图片文件、音视频文件等
是二进制数据,这种数据用文本打开后我们读不懂。
字符输入流的超类:Reader子类:FileReader、BufferReader
字符输出流的超类:Writer子类:FileWriter、BufferWriter
字节输入流的超类:InputStream子类:FileInputStream
字节输出流的超类:OutputStream子类:FileOutputStream

字符流

 关闭缓冲区语句外的try...catch外使用if语句判断相应流的对象是否为空,再使用finally语句将上述代码括起来。
 将输入、输出流的对象在方法一开始赋值为空,再创建其对象,这样方便关闭资源。

 输出(FileWriter)

  使用字符流向一个文件中写入内容的步骤:
①创建目标文件或定位到目标文件
②创建输出流对象
③将输出流指向目标文件
④做相应操作
⑤刷新输出流的缓冲区
⑥释放资源
注意:在使用相对路径时做操作时,待代码运行完毕后,在相应项目上右键刷新才能看到新创建的文件!

  常用构造器(覆盖写入)

FileWriter(File file) 
给一个File对象构造一个FileWriter对象。
例:
//										"文件名.xxx"
FileWriter fw = new FileWriter(new File("Test.txt"));
---------------------------------------------------------------------------------
FileWriter(String fileName) 
构造一个给定文件名的FileWriter对象。 
例:
//								"文件名.xxx"
FileWriter fw = new FileWriter("Test.txt");
---------------------------------------------------------------------------------

  常用方法

返回值类型			方法名	参数列表
void 				write(String str) 
写入一个字符串   
---------------------------------------------------------------------------------
abstract void 		flush() 
刷新流。 
---------------------------------------------------------------------------------
abstract void 		close() 
关闭流,先刷新。
---------------------------------------------------------------------------------
void 				write(char[] cbuf) 
写入一个字符数组。 
	public static void main(String[] args){
		//创建目标文件,此处使用的为相对路径的目录
		File file = new File("Test.txt");
		FileWriter fw = null;
		try {
			//创建输出流对象,并将输出流指向目标文件
			 fw = new FileWriter(file);
			//写入字符串
			fw.write("HelloWorld!");
			//写入字符数组
			char[] ch = {'a','b','c','d','e','f','g','h'};
			fw.write(ch);
			//刷新(清空)缓冲区,将内容写入到文件中
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//判断输出流是否为空
			if(fw != null) {
				try {
					//关闭输出流,释放资源
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

运行结果:在项目中将会产生一个Test.txt文件,文件内容为:HelloWorld!abcdefgh

  构造器部分改进代码:

	public static void main(String[] args){
		//,此处使用的为相对路径的目录
		FileWriter fw = null;
		try {
			//创建输出流对象,自动创建目标文件并将输出流指向目标文件
			 fw = new FileWriter("Test.txt");

  缓冲区可能溢出的问题

  虽然flush方法会当缓冲区存满后自动写入,但是效率不高,还有可能发生缓冲区溢出的情况,所以我们要手动调节。
  例如下面的代码,向文件中写入100个HelloWorld!,我们可以每到10次写入之后做一次缓冲区清空。

for(int i = 0;i<100;i++){
	fw.write("HelloWorld!");
	if(i%10 == 0){
	fw.flush();
	}
}

  常用构造器(追加写入)

当第二个参数为true时,将追加写入

FileWriter(File file, boolean append) 
给一个File对象构造一个FileWriter对象。
例:
//										"文件名.xxx"
FileWriter fw = new FileWriter(new File("Test.txt"),true);
---------------------------------------------------------------------------------
FileWriter(String fileName, boolean append) 
构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。 
例:
//								"文件名.xxx"
FileWriter fw = new FileWriter("Test.txt",true);
---------------------------------------------------------------------------------

  写入换行

WinousLinuxMac
\r\n\n\r

  建议使用"\r\n",可兼容Windows记事本。若为"\n\r"将会存在空行。
例:fw.write("字符串"+"\r\n");

  常用方法

abstract void write(char[] cbuf, int off, int len) 
写入字符数组的一部分。
---------------------------------------------------------------------------------
void write(int c) 
写一个字符  
---------------------------------------------------------------------------------
void write(String str, int off, int len) 
写一个字符串的一部分。  
---------------------------------------------------------------------------------
	public static void main(String[] args){
		FileWriter fw = null;
		try {
			//创建输出流对象,自动创建目标文件并将输出流指向目标文件
			 fw = new FileWriter("Test.txt",true);
			//写入字符串选定的部分
			fw.write("HelloWorld!",0,5);
			//写入字符数组选定的部分
			char[] ch = {'a','b','c','d','e','f','g','h'};
			fw.write(ch,0,4);
			//这里的98对应的是b
			fw.write(98);
			//刷新(清空)缓存区,将内容写入到文件中
			fw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//判断输出流是否为空
			if(fw != null) {
				try {
					//关闭输出流,释放资源
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

运行结果:Test.txt文件中将有Helloabcdb内容。

 输入(FileReader)

  读取一个名为文件名.xxx的内容并打印到控制台
①创建输入流对象
②读取数据
③关闭输入流

  常用构造器

FileReader(File file) 
创建一个新的 FileReader ,给出 File读取。 
---------------------------------------------------------------------------------
FileReader(String fileName) 
创建一个新的 FileReader ,给定要读取的文件的名称。 
---------------------------------------------------------------------------------

  常用方法

返回值类型				方法名	参数列表
int 					read() 
读一个字符 (当返回值为-1时表示此文件已读取完毕)(若文件中存在换行也将会读取到)
例:
	public static void main(String[] args) {
		FileReader fr = null;
		try {
			//此处需要try...catch来捕获文件未找到异常
			 fr = new FileReader("Test.txt");
			 int num = 0;
			 //当read方法读取完数据后会返回-1,所以我们使用while循环判断
			 //此处需要try...catch来捕获IO流异常
			 while((num = fr.read())!=-1) {
				 //read方法返回值类型为字符对应的ASCII码
				 System.out.print(num+" ");
				//如果想要打印原始字符,需要强制转换
				//若要使用这条输出语句需要注释上一行的输出语句!
//				 System.out.print((char)num+" ");
			 }
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		//这里没有重新try...catch,而是使用try...catch...catch
		}catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
输出结果:
72 101 108 108 111 87 111 114 108 100 33
强转后的输出结果:
H e l l o W o r l d ! 
---------------------------------------------------------------------------------
int 					read(char[] cbuf) 
将字符读入数组。 (当返回值为-1时表示此文件已读取完毕)(若文件中存在换行也将会读取到)
例:
	public static void main(String[] args) {
		FileReader fr = null;
		try {
			//此处需要try...catch来捕获文件未找到异常
			 fr = new FileReader("Test.txt");
			 int num = 0;
			 char[] ch = new char[15];
			 //当read方法读取完数据后会返回-1,所以我们使用while循环判断
			 //此处需要try...catch来捕获IO流异常
			 while((num = fr.read(ch))!=-1) {
				 //此处read方法返回值为读取到的字符长度
				 System.out.print(num+" ");
			 }
			 //此处直接将char数组转换为字符串类型
			 String str = new String(ch);
			 System.out.println(ch);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		//这里没有重新try...catch,而是使用try...catch...catch
		}catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
输出结果:

---------------------------------------------------------------------------------
abstract int 			read(char[] cbuf, int off, int len) 
将字符读入数组的一部分。 (若文件中存在换行也将会读取到)
(off为在数组中存入字符的起始位置,len为存入字符的长度)
例:
	public static void main(String[] args) {
		FileReader fr = null;
		try {
			//此处需要try...catch来捕获文件未找到异常
			 fr = new FileReader("Test.txt");
			 int num = 0;
			 char[] ch = new char[20];
			 //当read方法读取完数据后会返回-1,所以我们使用while循环判断
			 //此处需要try...catch来捕获IO流异常
			 //这里使用read方法将指定长度的字符读入到数组中指定位置
			 while((num = fr.read(ch,1,8))!=-1) {
				 //此处指定输出存入char数组中的字符
				 System.out.println(new String(ch,0,5));
			 }
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		//这里没有重新try...catch,而是使用try...catch...catch
		}catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
输出结果:

---------------------------------------------------------------------------------

  注意:read(char[] cbuf, int off, int len) 在此方法中,read方法将字符读入数组后并不是永久存储,只是暂时存储,并且会被覆盖!
  例如:Test.txt中存储的字符为HelloWorld!abcde

		FileReader fr = null;
			 fr = new FileReader("Test.txt");
			 int num = 0;
			 char[] ch = new char[20];
			 while((num = fr.read(ch,1,8))!=-1) {
				 System.out.println(new String(ch,0,5));
			 }

数组中的变化结果如下:
 第一次返回值不为-1
[ ,H,e,l,l,o,W,o,r, ]
输出结果:
Hell
 第二次返回值不为-1
[ ,l,d,!,a,b,c,d,e, ]
输出结果:
ld!a
 第三次返回值为-1
  由上方代码可知数组的作用只是暂存,并不是永久存储,read方法中参数int off是指存入数组中的位置,new String构造方法中参数int off是指读取数组中参数的起始位置。
  所以推荐写法如下:

	public static void main(String[] args) {
		FileReader fr = null;
		try {
			//此处需要try...catch来捕获文件未找到异常
			 fr = new FileReader("Test.txt");
			 int len = 0;
			 char[] ch = new char[10];
			 //当read方法读取完数据后会返回-1,所以我们使用while循环判断
			 //此处需要try...catch来捕获IO流异常
			 //这里使用read方法将指定长度的字符读入到数组中指定位置
			 while((len = fr.read(ch))!=-1) {
				 //此处指定输出存入char数组中的字符
				 System.out.print(new String(ch,0,len));
				 System.out.println();
			 }
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		//这里没有重新try...catch,而是使用try...catch...catch
		}catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(fr != null) {
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

文本文件的复制(FileWriter FileReader)

  步骤:
①创建字符输入流对象
②创建字符输出流对象
③将输入流的数据写入输出流中
④关闭资源

public class CopyFileTest {
	public static void main(String[] args) {
		copyFile();
	}
	public static void copyFile() {
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fr = new FileReader("Test.txt");
			fw = new FileWriter("AAA.txt",true);
			int len = 0;
			char[] ch = new char[1024];
			while((len = fr.read(ch)) != -1) {
				fw.write(len);
				fw.flush();
			}
		}catch(FileNotFoundException e) {
			e.printStackTrace();
		}catch(IOException e) {
			e.printStackTrace();
		}finally{
			if(fr != null && fw != null) {
				try {
					fr.close();
					fw.close();
				}catch(IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

  其中对于写入的代码可以有另一种方式

public class CopyFileTest {
	public static void main(String[] args) {
		copyFile();
	}
	public static void copyFile() {
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fr = new FileReader("Test.txt");
			fw = new FileWriter("AAA.txt",true);
			//从这里开始使用了另外一种方式
			int num = 0;
			while((num = fr.read()) != -1) {
				fw.write();
				fw.flush();
			}
		}catch(FileNotFoundException e) {
			e.printStackTrace();
		}catch(IOException e) {
			e.printStackTrace();
		}finally{
			if(fr != null && fw != null) {
				try {
					fr.close();
					fw.close();
				}catch(IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

BufferedWriter

  BufferedWriter:高效缓冲区输出流。将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

 常用构造器

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

 扩展方法

  由于FileWriter与BufferedWriter都继承与Writer,所以方法基本都一致,有一个BufferedWriter自己的常用扩展方法。

void 					newLine() 
写一行行分隔符。(相当于之前讲的换行("\r\n"))
例:
	public static void main(String[] args) {
		FileWriter fw = null;
		BufferedWriter bw = null;
		try {
			//创建输出流
			fw = new FileWriter("Test.txt");
			//创建高效缓冲区输出流
			bw = new BufferedWriter(fw);
			//当需要指定缓冲大小时,需要使用此构造器
//			bw = new BufferedWriter(fw,1024);
			//将目标数据写入文件
			bw.write("测试写入,写入成功!");
			//写入一个换行符
			bw.newLine();
			bw.write("测试写入,写入成功!");
			//清空缓冲区
			bw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if(bw != null) {
				try {
					//当关闭BufferWriter时会自动关闭FileWriter
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

BufferedReader

  BufferedReader:高效缓冲区输入流。从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

 常用构造器

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

 一般用法

	public static void main(String[] args) {
		FileReader fr = null;
		BufferedReader br = null;
		try {
//			创建输入流
			fr = new FileReader("Test.txt");
//			创建高效缓冲区输入流
			br = new BufferedReader(fr);
			int num = -1;
			char[] ch = new char[1024];
//			判断是否读取到文件内容的末尾
			while((num = br.read(ch)) != -1) {
//				使用String构造器打印所读取到的数据
				System.out.println(new String(ch,0,num));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch(IOException e) {
			e.printStackTrace();
		}finally {
			if(br != null) {
				try {
//					关闭高效缓冲区输入流,释放资源
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

 扩展方法

  由于FileReader与BufferedReader都继承与Reader,所以方法基本都一致,有一个BufferedReader自己的常用扩展方法。

String 				readLine() 
读取一个文本行。 (当没有足够数据时会返回null)
例:
	public static void main(String[] args) {
		FileReader fr = null;
		BufferedReader br = null;
		try {
//			创建输入流
			fr = new FileReader("Test.txt");
//			创建高效缓冲区输入流
			br = new BufferedReader(fr);
			String line = null;
//			判断数据是否为空
			while((line = br.readLine()) != null) {
				System.out.println(line);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch(IOException e) {
			e.printStackTrace();
		}finally {
			if(br != null) {
				try {
//					关闭高效缓冲区输入流,释放资源
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

文本文件的复制(BufferWriter BufferReader)

  步骤:
①创建字符输入流对象
②创建高效缓冲区的输入流对象
③创建字符输出流对象
④创建高效缓冲区的输出流对象
⑤读取数据并写入到另一个文件中
⑥释放资源

public class BufferCopyTest {

	public static void main(String[] args) {
		copyFiles();
	}
		public static void copyFiles() {
//			创建字符输入流对象
			FileReader fr = null;
//			创建高效缓冲区输入流对象
			BufferedReader bfr = null;
//			创建字符输出流对象
			FileWriter fw = null;
//			创建高效缓冲区输出流对象
			BufferedWriter bfw = null;
			
			try {
				fr = new FileReader("Test.txt");
				bfr = new BufferedReader(fr);
				fw = new FileWriter("AAA.txt");
				bfw = new BufferedWriter(fw);
				
				String str = null;
//				使用readLine方法,并判断是否为空
				while((str = bfr.readLine()) != null) {
//					将数据输出到目标文件中
					bfw.write(str);
//					当源文件中有换行时副本文件也会换行
					bfw.newLine();
				}
//					刷新缓冲区
					bfw.flush();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}catch (IOException e) {
				e.printStackTrace();
			}finally {
				if(bfw != null && bfr != null) {
					try {
//						关闭输入、输出流,释放资源
						bfr.close();
						bfw.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值