本系列博客汇总在这里:Java系列_汇总
目录
一、IO 流概述
- IO(Input/Output):输入和输出,指的是某个设备或环境进行数据的输入或者输出。例如:键盘的输入,再比如显示器就是输出设备,输出图像。
- 对于java来说输入输出问题,java将它抽象成流对象来解决。
- 以游戏程序为中心读取文件就是输入,写入文件是输出。
二、IO 流在 java 中的分类
三、字符流简介
-
输出流
(1)字符输出流的超类:Writer;
(2)子类 :FileWriter,BufferedWriter,…
-
输出流
(1)字符输入流的超类:Reader;
(2)子类: FileReader,BufferedReader,…
-
使用字符流向一个文件输入helloworld
步骤:
(1)创建文件;
(2)创建输出流对象;
(3)把流指向指定的文件;
(4)释放资源。
四、字符输出流 FileWriter
-
FileWriter 的普通构造器(会覆盖原有内容)
构造器一//创建文件 File file = new File("a.txt"); FileWriter fw = null; try { //创建输出流的对象 fw = new FileWriter(file); //把内容写入文件 fw.write("helloworld"); //字符流的特点:清空缓冲区,把内容写入到文件中 fw.flush(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }finally { if(fw != null) { try { //close关闭输出流时会自动清理缓冲区 fw.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
构造器二//可以不用手动创建文件对象 //File file = new File("a.txt"); FileWriter fw = null; try { //创建输出流的对象 fw = new FileWriter("a.txt"); //把内容写入文件 fw.write("helloworld"); //字符流的特点:清空缓冲区,把内容写入到文件中 fw.flush(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }finally { if(fw != null) { try { //close关闭输出流时会自动清理缓冲区 fw.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
-
flush 的使用注意事项
FileWriter fw = null; try { //创建输出流的对象 fw = new FileWriter("b.txt"); //向文件中写入100个helloworld for (int i = 0; i < 100; i++) { //把内容写入文件 //把文本写入文件中 \n 代表换行,同时为了兼容记事本,建议使用 \r\n fw.write("helloworld\n"); if(i%10 == 0) { //清空缓冲区,把内容写入到文件中,当数据量较大,不应该在最后才清空缓冲区,但也不应该频繁清空缓冲区 fw.flush(); } } //把缓冲区最后残留的数据写入文件 fw.flush(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }finally { if(fw != null) { try { //close关闭输出流时会自动清理缓冲区 fw.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
-
FileWriter 的追加构造器
示例FileWriter fw = null; try { //创建输出流的对象的两种方式 fw = new FileWriter("b.txt",true);//推荐使用 //fw = new FileWriter(new File("b.txt"),true); //向文件中写入100个helloworld for (int i = 0; i < 100; i++) { //把内容写入文件 //把文本写入文件中 \n 代表换行,同时为了兼容记事本,建议使用 \r\n fw.write("weiyuxuan\n"); if(i%10 == 0) { //清空缓冲区,把内容写入到文件中,当数据量较大,不应该在最后才清空缓冲区,但也不应该频繁清空缓冲区 fw.flush(); } } //把缓冲区最后残留的数据写入文件 fw.flush(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }finally { if(fw != null) { try { //close关闭输出流时会自动清理缓冲区 fw.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
注意:输出换行不同的环境下换行的方式也不一样!
(1)Windows: \r\n(使用 \n\r 时由于 \r 的作用会多空出一行,当记事本打开的时候,应该使用 \r\n 才能按预期显示)
(2)Linux: \n
(3)Mac: \r
四、FileWriter 的五种写入功能
- 示例
FileWriter fw = null; try { //创建输出流的追加对象 fw = new FileWriter("text.txt"); /** * 第一种(写入字符数组) */ char[] cha = {'a','b','c','d'}; fw.write(cha); /** * 第二种 */ //把一部分的字符数组写入到文件,第一个参数是字符数组,第二个参数是开始索引,第三个参数是从开始索引开始取得字符串的长度 fw.write(cha, 1, 3); /** * 第三种 */ //通过int值写入相应的字符 fw.write(100); /** * 第四种 */ //写入字符串 fw.write("100"); /** * 第五种 */ //截取字符串 fw.write("weiyuxuan", 2, 3); //清空缓冲区,把内容写入到文件中 fw.flush(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }finally { if(fw != null) { try { //close关闭输出流时会自动清理缓冲区 fw.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
五、字符输入流 FileReader
-
FileReader 并不是 Reader 的直接子类
-
FileReader 的构造器
构造器类似 FileWriter ,第一种构造器同之前一样,需要预先创建文件对象,推荐使用第二种构造器! -
范例:读取文件 helloworld.txt 打印到控制台
(1)创建出入流对象 FileReader;
(2)读取数据;
(3)关闭输入流。 -
读取字符的方法
第一种读取方式:读取单个字符,返回的是字符的ASCII码//创建文件读取对象 FileReader fr = new FileReader("text.txt"); /* //第一次读取第一个字符 int num = fr.read(); System.out.println((char)num); //第二次读取第二个字符 num = fr.read(); System.out.println((char)num); */ //如果整个文本读取完毕,最后没有字符会返回 -1 int num = 0; //通过循环来读取字符,判断跳出循环的标志是 num=-1 while((num = fr.read()) != -1) { System.out.print((char)num); }
第二种读取方式:把字符读入数组,返回读取到的字符数量//创建文件读取对象 FileReader fr = new FileReader("text.txt"); //读取5个字符放入到字符数组中(包括换行符) char[] chs = new char[15]; //第一次读取 System.out.println("-------------------------------------"); int num = fr.read(chs); String str = new String(chs); System.out.println(num); System.out.println(str); //第二次读取 System.out.println("-------------------------------------"); num = fr.read(chs); str = new String(chs); System.out.println(num); System.out.println(str); //第三次读取 System.out.println("-------------------------------------"); //为什么要如下这样做? //因为读取字符类似分批读取处理的,当字符数量不足一批,此处就是不足15的话,假如说到最后只剩12个字符了由于 //机制上是覆盖原数据上一批的数据,但是由于只有12个字符可供读取,所以从13开始将无法覆盖上一批的字符,当然 //也就保留上一批的字符了,所以我们需要进行如下操作: num = fr.read(chs); if( num < 15) { //读取剩余字符 str = new String(chs,0,num); } System.out.println(num); System.out.println(str);
FileReader fr = null; //创建文件读取对象 fr = new FileReader("text.txt"); //读取5个字符放入到字符数组中(包括换行符) char[] chs = new char[15]; //第一次读取 System.out.println("-------------------------------------"); int num = fr.read(chs); String str = new String(chs,0,num); System.out.println(num); System.out.println(str); //第二次读取 System.out.println("-------------------------------------"); num = fr.read(chs); str = new String(chs,0,num); System.out.println(num); System.out.println(str); //第三次读取 System.out.println("-------------------------------------"); num = fr.read(chs); str = new String(chs,0,num); System.out.println(num); System.out.println(str);
输出
//创建文件读取对象 FileReader fr = new FileReader("text.txt"); //读取1024个字符放入到字符数组中(包括换行符) char[] chs = new char[1024]; int len = -1; //循环条件判断的边界是fr.read(chs)返回-1,说明文件已经读取完毕 while((len = fr.read(chs)) != -1) { System.out.println(new String(chs,0,len)); }
六、文本文件的复制
-
使用字符流来做文件的拷贝。
-
范例:把一个java文件拷贝到项目根目录。
(1)创建字符输入流的对象;
(2)创建字符输出流对象;
(3)把输出流输入的数据写入输出流中;
(4)关闭资源。 -
示例
Reader reader = null; Writer writer = null; try { //创建读文件对象 reader = new FileReader("src/cn/wyx/io/cha/IODemo.java"); //创建写文件对象 writer = new FileWriter("IODemo.java"); int num = -1; while((num = reader.read()) != -1) { writer.write(num); } } catch (FileNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } finally { //释放资源 try { if(writer != null) { writer.close(); } if(reader != null) { reader.close(); } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } }
public static void copyFile() { Reader reader = null; Writer writer = null; try { //创建读文件对象 reader = new FileReader("src/cn/wyx/io/cha/IODemo.java"); //创建写文件对象 writer = new FileWriter("IODemo.java"); //定义每次读取长度的对象 int len = -1; //定义存储内容的数组 char[] chs = new char[1024]; //当 len!=-1 就一直读 while((len = reader.read(chs)) != -1) { //把读取的文件写入到目标文件中 writer.write(chs,0,len); } } catch (FileNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } finally { //释放资源 try { if(writer != null) { writer.close(); } if(reader != null) { reader.close(); } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
七、BufferedWriter 高效缓存区输出流
- 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
- 构造器
- 示例
/** * * 描述:使用高效缓冲区流来将 text.txt 的文件中写入“临渊羡鱼,不如退而织网” */ public static void writer() { //创建文件输出流 FileWriter fw = null; BufferedWriter bw = null; try { fw = new FileWriter("text.txt"); //创建高效缓冲区的流对象 bw = new BufferedWriter(fw); //输出数据 bw.write("临渊羡鱼,不如退而织网"); //清空缓冲区 bw.flush(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } finally { if(bw != null) { try { //释放资源 bw.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } }
八、BufferedReader 高效缓存区输入流
- 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
- 构造器
- 使用高效缓冲区输入流来读取文件中的内容。
- 示例
/** * * 描述:使用高效缓冲区流来将 text.txt 文件中的内容读出来 */ public static void reader() { //创建文件输入流 FileReader fr = null; BufferedReader br = null; try { fr = new FileReader("text.txt"); //创建高效缓冲区的流对象 br = new BufferedReader(fr); char[] chs = new char[1024]; int len = -1; while((len = br.read(chs)) != -1) { System.out.print(new String(chs,0,len)); } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } finally { if(br != null) { try { //释放资源 br.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } }
九、高效缓存区的扩展方法
-
输出流
示例fw = new FileWriter("text.txt"); //创建高效缓冲区的流对象 bw = new BufferedWriter(fw); for (int i = 0; i < 10; i++) { //输出数据 bw.write("临渊羡鱼,不如退而织网"); //换行,相当于\r\n,该方法能兼容记事本! bw.newLine(); } //清空缓冲区 bw.flush();
-
输入流
示例//创建文件读取对象 FileReader fr = new FileReader("text.txt"); //创建高效缓冲区的流对象 BufferedReader br = new BufferedReader(fr); String line = br.readLine(); //高效输入流可以读取一行数据 while((line = br.readLine()) != null) { System.out.println(line); }
十、使用高效缓存区流复制文件
- 示例
最后注意:当前学习的字符流只能对文本文件进行操作!public static void copyFile() { Reader reader = null; BufferedReader br = null; BufferedWriter bw = null; Writer writer = null; try { //创建读文件对象 reader = new FileReader("src/cn/wyx/io/cha/IODemo.java"); //创建高效缓冲区的输入流 br = new BufferedReader(reader); //创建写文件对象 writer = new FileWriter("IODemo.java"); //创建高效缓冲区的输出流 bw = new BufferedWriter(writer); String line = null; //读取数据并且写入另一个文件中 while((line= br.readLine()) != null) { bw.write(line); bw.newLine(); } //清空缓冲区 bw.flush(); } catch (FileNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } finally { //释放资源 try { if(writer != null) { writer.close(); } if(reader != null) { reader.close(); } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } }
如有错误,欢迎指正!