Java IO流
IO流用来处理设备之间的数据传输;
所有的数据都可以用字节流来进行传输(因为最终都是转化为二进制数据来传输);而常见的文件就可以用字符流来进行传输,效率更高,更方便;
JavaIO中四个顶层抽象类:
InuputStream:输入字节流;
OutputStream:输出字节流;
Reader:输入字符流;
Writer:输出字符流;
四个基类的子类名称都以四个基类作为后缀,前面就表示子类的功能;
通过InputStream读文件内容的步骤:(读数据的过程)
1、找到所读文件路径(找到文件路径)
2、创建输入流对象(创建流对象)
3、读文件内容(读写内容)
4、关闭输入流(关闭流)
通过OutputStream写内容仅文件的步骤:(写数据的过程)
1、找到写入内容的文件路径;
2、创建输出流对象;
3、定义需要写入的内容;
4、将内容写入文件;
5、关闭输出流;
流操作的基本规律:
1.明确来源和目的;
来源:输入流; InputStream Reader
目的:输出流; OutputStream Writer
2.明确是否是纯文本;
是:字符流
不是:字节流
3.前两步明确后,再明确具体的对象;
通过设备来进行区分:
来源:内存、硬盘、键盘;
目的:内存、硬盘、控制台;
4.需不需要提高效率;
5.是否需要加入指定的编码表,默认是GBK,指定用UTF-8,只有转换流能指定编码表;
流只能操作数据,而想要操作文件,必须用File对象;
一些实例:
1 package IO; 2 3 /** 4 * FileWriter 5 * 代码有很大缺陷 6 */ 7 import java.io.FileWriter; 8 import java.io.IOException; 9 10 public class FileWriterDemo 11 { 12 public static void main(String[] args) throws IOException 13 { 14 // 明确数据存放位置 15 FileWriter fw = new FileWriter("demo.txt"); // 文件可以不存在;如果已存在,会被覆盖掉 16 // FileWriter fr = new FileWriter("f:\\demo.txt"); 17 // 将字符串写入流中,文件中现在并没有数据,流的内部有缓冲,先保存数据 18 fw.write("abcd"); 19 // 将流中缓存的数据刷到文件中,这步必须要有 20 fw.flush(); 21 // 先刷新一次流中的数据,再关闭 22 // 与flush()的区别:flush()之后可以再接着flush(),而close()之后,流被关闭,不能再被flush(),因为不能再写入数据了 23 fw.close(); 24 } 25 }
1 package IO; 2 3 /** 4 * IO的异常处理 5 */ 6 import java.io.FileWriter; 7 import java.io.IOException; 8 9 public class FileWriterDemo2 10 { 11 public static void main(String[] args) 12 { 13 FileWriter fw = null; // 在try外创建引用 14 try 15 { 16 // 在try内进行初始化 17 fw = new FileWriter("demo.txt"); // 注意点1:路径可能会写错 18 fw.write("abcdef"); 19 } 20 catch (IOException e) 21 { 22 System.out.println(e); 23 } 24 finally 25 { 26 try 27 { // 注意点3:关闭流本身也还会抛出异常 28 // 关闭流操作要写到finally中 29 // 如果有多个流都没关闭,要分别进行关闭,不要一次性全关闭 30 if (fw != null) // 注意点4:如果fw为空,则fw.close()这样写肯定报空指针异常,所以必须进行非空判断 31 { 32 fw.close(); // 注意点2:变量的作用域问题 33 } 34 } 35 catch (IOException e) 36 { 37 e.printStackTrace(); 38 } 39 } 40 } 41 }
1 package IO; 2 3 import java.io.FileWriter; 4 import java.io.IOException; 5 6 /** 7 * 对已有文件数据续写:写在文件的末尾 8 */ 9 public class FileWriterDemo3 10 { 11 public static void main(String[] args) 12 { 13 FileWriter fw = null; 14 try 15 { 16 // 通过构造函数,实现在文件末尾添加数据 17 // 且:传递一个true参数,代表不覆盖已有文件 18 fw = new FileWriter("demo.txt",true); 19 fw.write("abc\r\ndef"); // \r\n表示换行 20 } catch (IOException e) 21 { 22 e.printStackTrace(); 23 } 24 finally 25 { 26 if(fw != null) 27 { 28 try 29 { 30 fw.close(); 31 } catch (IOException e) 32 { 33 e.printStackTrace(); 34 } 35 } 36 } 37 } 38 }
1 package IO; 2 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 /** 7 * 通过字符流读取文件内容 8 */ 9 public class FileReaderDemo 10 { 11 public static void main(String[] args) 12 { 13 FileReader fr = null; 14 try 15 { 16 // 文件必须存在,不然会抛出文件未找到异常 17 fr = new FileReader("demo.txt"); 18 19 int ch = 0; 20 // 字符在计算机中是以数字存在的,所以要用int来接收 21 // read():一次读一个字符,而且会自动往下读 22 // -1:表示到了数据末尾,没有数据了 23 while((ch=fr.read()) != -1) 24 { 25 System.out.print((char)ch); 26 } 27 } 28 catch (FileNotFoundException e) 29 { 30 e.printStackTrace(); 31 } 32 catch (IOException e) 33 { 34 e.printStackTrace(); 35 } 36 finally 37 { 38 if(null != fr) 39 { 40 try 41 { 42 fr.close(); 43 } catch (IOException e) 44 { 45 e.printStackTrace(); 46 } 47 } 48 } 49 } 50 }
1 package IO; 2 3 import java.io.FileNotFoundException; 4 import java.io.FileReader; 5 import java.io.IOException; 6 7 /** 8 * 通过字符数组读取文件内容 9 */ 10 public class FileReaderDemo2 11 { 12 public static void main(String[] args) 13 { 14 FileReader fr = null; 15 try 16 { 17 fr = new FileReader("demo.txt"); 18 int ch = 0; 19 // 通常情况下定义成1024的整数倍 20 char[] buff = new char[1024]; //2K空间 21 // 返回读取的字符数 22 while((ch=fr.read(buff)) != -1) 23 { 24 // 以字符串形式输出,只截取需要的部分 25 System.out.println(new String(buff,0,ch)); 26 } 27 } 28 catch (FileNotFoundException e) 29 { 30 e.printStackTrace(); 31 } 32 catch (IOException e) 33 { 34 e.printStackTrace(); 35 } 36 finally 37 { 38 if(null != fr) 39 { 40 try 41 { 42 fr.close(); 43 } catch (IOException e) 44 { 45 e.printStackTrace(); 46 } 47 } 48 } 49 } 50 }
1 package IO; 2 /** 3 * 读文件内容并打印到控制台 4 */ 5 import java.io.FileNotFoundException; 6 import java.io.FileReader; 7 import java.io.IOException; 8 9 public class Practise1 10 { 11 public static void main(String[] args) 12 { 13 FileReader fr = null; 14 try 15 { 16 // 只要指定文件名就可以了 17 fr = new FileReader("f:\\DeadLockTest.java"); 18 char[] buff = new char[1024]; 19 int num = 0; 20 while((num=fr.read(buff)) != -1) 21 { 22 // 不要用println();如果读到数据到了1024个字符,会空一行再打印内容 23 // 输出就相当于打印到控制台上 24 System.out.print(new String(buff,0,num)); 25 } 26 } 27 // 读文件必出现的两个异常:文件未找到异常 28 catch (FileNotFoundException e) 29 { 30 e.printStackTrace(); 31 } 32 // 读文件必要的两个异常:IO异常 33 catch (IOException e) 34 { 35 e.printStackTrace(); 36 } 37 finally 38 { 39 if(null != fr) 40 { 41 try 42 { 43 fr.close(); 44 } catch (IOException e) 45 { 46 e.printStackTrace(); 47 } 48 } 49 } 50 } 51 }
1 package IO; 2 /** 3 * 文件拷贝 4 */ 5 import java.io.FileReader; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 9 public class FileCopyDemo 10 { 11 public static void main(String[] args) 12 { 13 // methodOne(); 14 methodTwo(); 15 } 16 17 // 法一:一次只读一个字符 18 public static void methodOne() 19 { 20 FileWriter fw = null; 21 FileReader fr = null; 22 try 23 { 24 fw = new FileWriter("d:\\DeadLockTest_copy.txt"); 25 fr = new FileReader("f:\\DeadLockTest.java"); 26 27 int ch = 0; 28 while((ch=fr.read()) != -1) 29 { 30 fw.write(ch); 31 } 32 } 33 catch (IOException e) 34 { 35 e.printStackTrace(); 36 } 37 finally 38 { 39 if(null != fw) 40 try 41 { 42 fw.close(); 43 } catch (IOException e) 44 { 45 e.printStackTrace(); 46 } 47 if(null != fr) 48 try 49 { 50 fr.close(); 51 } catch (IOException e) 52 { 53 e.printStackTrace(); 54 } 55 } 56 } 57 58 // 法二:一次读一个字符数组 59 public static void methodTwo() 60 { 61 FileWriter fw = null; 62 FileReader fr = null; 63 try 64 { 65 fw = new FileWriter("d:\\DeadLockTest_Copy.txt"); 66 fr = new FileReader("f:\\DeadLockTest.java"); 67 68 char[] buff = new char[1024]; 69 int num = 0; 70 71 while((num=fr.read(buff)) != -1) 72 { 73 fw.write(buff,0,num); 74 } 75 } 76 catch (IOException e) 77 { 78 e.printStackTrace(); 79 } 80 finally 81 { 82 if(null != fw) 83 try 84 { 85 fw.close(); 86 } catch (IOException e) 87 { 88 e.printStackTrace(); 89 } 90 if(null != fr) 91 try 92 { 93 fr.close(); 94 } catch (IOException e) 95 { 96 e.printStackTrace(); 97 } 98 } 99 100 } 101 }
1 package IO; 2 /** 3 * 文件缓冲流:BufferedReader 4 * 装饰者模式:当想要对已有功能对象进行增强时,自定义类,将对象放入,基于已有的功能,提供加强功能; 5 * 这个自定义类就是装饰类;(以前读一个字符,现在可以直接读一行的字符) 6 */ 7 import java.io.BufferedReader; 8 import java.io.FileNotFoundException; 9 import java.io.FileReader; 10 import java.io.IOException; 11 12 public class BufferedReaderDemo 13 { 14 public static void main(String[] args) 15 { 16 FileReader fr = null; 17 BufferedReader br = null; 18 try 19 { 20 fr = new FileReader("demo1.txt"); // 有异常 21 br = new BufferedReader(fr); // 有异常 22 String line = null; 23 // 读到末尾返回空 24 while((line=br.readLine()) != null) // 有异常 25 { 26 System.out.println(line); 27 } 28 } 29 catch (FileNotFoundException e) 30 { 31 e.printStackTrace(); 32 } 33 catch (IOException e) 34 { 35 e.printStackTrace(); 36 } 37 finally 38 { 39 if(null != br) 40 { 41 try 42 { 43 // 关闭缓冲区,其实就是在关闭缓冲区中的流对象,所以不用再一次关闭流对象了 44 br.close(); // 有异常 45 } catch (IOException e) 46 { 47 e.printStackTrace(); 48 } 49 } 50 } 51 } 52 }
1 package IO; 2 /** 3 * 文件缓冲流:BufferedWriter 4 */ 5 import java.io.BufferedWriter; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 9 public class BufferedWriterDemo 10 { 11 public static void main(String[] args) throws IOException 12 { 13 FileWriter fw = new FileWriter("f:\\demo.txt"); 14 // 构造函数中必须要有流对象 15 BufferedWriter bw = new BufferedWriter(fw); 16 bw.write("asdfghjkl"); 17 // 换行,跨平台 18 bw.newLine(); 19 bw.write("zxcvbnm"); 20 // 这条语句必须加:只要用到缓冲区,就要记得刷新 21 bw.flush(); 22 // 缓冲流关闭之后,文件流不需要再手动关闭了 23 bw.close(); 24 25 test(); 26 } 27 28 public static void test() throws IOException 29 { 30 // 如果事先不存在这个文件,会自动创建这个文件 31 FileWriter fw = new FileWriter("f:\\demo1.txt"); 32 // 构造函数中必须要有流对象 33 BufferedWriter bw = new BufferedWriter(fw); 34 for(int i=1;i<100;i++) 35 { 36 bw.write("asdf"); 37 bw.newLine(); 38 // 建议写一次,刷一次 39 bw.flush(); 40 } 41 // 缓冲流关闭之后,文件流不需要再手动关闭了 42 bw.close(); 43 } 44 }
1 package IO; 2 /** 3 * 文件拷贝,BufferedReader/BufferedWriter实现 4 */ 5 import java.io.BufferedReader; 6 import java.io.BufferedWriter; 7 import java.io.FileNotFoundException; 8 import java.io.FileReader; 9 import java.io.FileWriter; 10 import java.io.IOException; 11 12 public class FileCopyDemo2 13 { 14 public static void main(String[] args) 15 { 16 BufferedReader br = null; 17 BufferedWriter bw = null; 18 try 19 { 20 br = new BufferedReader(new FileReader("demo.txt")); 21 bw = new BufferedWriter(new FileWriter("demo1.txt")); 22 23 String line = null; 24 // readLine()只返回回车符之前的内容,并不返回回车符,所以要添加换一行那个方法 25 while((line=br.readLine()) != null) 26 { 27 bw.write(line); 28 // 这行必须要写 29 bw.newLine(); 30 bw.flush(); 31 } 32 } 33 catch (FileNotFoundException e) 34 { 35 e.printStackTrace(); 36 } 37 catch (IOException e) 38 { 39 e.printStackTrace(); 40 } 41 finally 42 { 43 if(null != br) 44 try 45 { 46 br.close(); 47 } catch (IOException e) 48 { 49 e.printStackTrace(); 50 } 51 if(null != bw) 52 try 53 { 54 bw.close(); 55 } catch (IOException e) 56 { 57 e.printStackTrace(); 58 } 59 } 60 } 61 }
1 package IO; 2 /** 3 * 装饰者模式:当想要对已有对象的功能进行增强时,自定义类,将对象放入,基于已有的功能,提供加强功能; 4 * 这个自定义类就是装饰类;(以前读一个字符,现在可以直接读一行的字符) 5 * 6 * 装饰者通常通过构造函数加入被装饰者对象,然后基于被装饰对象的功能,提供更强的功能; 7 */ 8 class Person 9 { 10 public void chifan() 11 { 12 System.out.println("吃饭"); 13 } 14 } 15 16 class SuperPerson 17 { 18 private Person p; 19 public SuperPerson(Person p) 20 { 21 this.p = p; 22 } 23 public void chifan() 24 { 25 System.out.println("开胃酒"); 26 p.chifan(); 27 System.out.println("甜点"); 28 System.out.println("来一根"); 29 } 30 } 31 public class PersonDemo 32 { 33 public static void main(String[] args) 34 { 35 /*Person p = new Person(); 36 p.chifan();*/ 37 38 Person p = new Person(); 39 SuperPerson sp = new SuperPerson(p); 40 sp.chifan(); 41 } 42 }
1 package IO; 2 /** 3 * LineNumberReader缓冲流的使用,BufferedReader的子类 4 */ 5 import java.io.FileNotFoundException; 6 import java.io.FileReader; 7 import java.io.IOException; 8 import java.io.LineNumberReader; 9 10 public class LineNuberReaderDemo 11 { 12 public static void main(String[] args) 13 { 14 FileReader fr = null; 15 LineNumberReader lnr = null; 16 try 17 { 18 fr = new FileReader("f:\\DeadLockTest.java"); 19 lnr = new LineNumberReader(fr); 20 String line; 21 // 设置行号从20开始,默认从0开始 22 lnr.setLineNumber(20); 23 while((line=lnr.readLine()) != null) 24 { 25 // 获取行号(在显示中添加行号) 26 System.out.println(lnr.getLineNumber() + ":" + line); 27 } 28 } 29 catch (FileNotFoundException e) 30 { 31 e.printStackTrace(); 32 } 33 catch (IOException e) 34 { 35 e.printStackTrace(); 36 } 37 finally 38 { 39 if(null != lnr) 40 { 41 try 42 { 43 lnr.close(); 44 } catch (IOException e) 45 { 46 e.printStackTrace(); 47 } 48 } 49 if(null != fr) 50 { 51 try 52 { 53 fr.close(); 54 } catch (IOException e) 55 { 56 e.printStackTrace(); 57 } 58 } 59 } 60 } 61 }
1 /** 2 * 功能:FileInputStream的使用 3 */ 4 package IO; 5 6 import java.io.FileInputStream; 7 import java.io.FileNotFoundException; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 11 public class FileStreamDeno 12 { 13 public static void main(String[] args) 14 { 15 // writeFile(); 16 // readFile_1(); 17 // readFile_2(); 18 // readFile_3(); 19 readFile_4(); 20 } 21 22 // 一次读一个字节 23 public static void readFile_1() 24 { 25 FileInputStream fis = null; 26 try 27 { 28 fis = new FileInputStream("f:\\fos.txt"); 29 int ch = 0; 30 31 while ((ch = fis.read()) != -1) 32 { 33 System.out.println((char) ch); 34 } 35 36 } catch (FileNotFoundException e) 37 { 38 e.printStackTrace(); 39 } catch (IOException e) 40 { 41 e.printStackTrace(); 42 } 43 44 } 45 46 // 一次读多个字节 47 public static void readFile_2() 48 { 49 FileInputStream fis = null; 50 try 51 { 52 fis = new FileInputStream("f:\\fos.txt"); 53 byte[] btr = new byte[2]; 54 int ch = 0; 55 while((ch=fis.read(btr)) != -1) 56 { 57 System.out.println(new String(btr,0,ch)); 58 } 59 } 60 catch(FileNotFoundException e) 61 { 62 e.printStackTrace(); 63 } 64 catch(Exception e) 65 { 66 e.printStackTrace(); 67 } 68 finally 69 { 70 if(null != fis) 71 try 72 { 73 fis.close(); 74 } catch (IOException e) 75 { 76 e.printStackTrace(); 77 } 78 } 79 } 80 81 // 读文件内容的字节数 82 public static void readFile_3() 83 { 84 FileInputStream fis = null; 85 try 86 { 87 fis = new FileInputStream("f:\\fos.txt"); 88 // 包括换行符 89 int num = fis.available(); 90 System.out.println(num); 91 } 92 catch(FileNotFoundException e) 93 { 94 e.printStackTrace(); 95 } 96 catch(Exception e) 97 { 98 e.printStackTrace(); 99 } 100 finally 101 { 102 if(null != fis) 103 try 104 { 105 fis.close(); 106 } catch (IOException e) 107 { 108 e.printStackTrace(); 109 } 110 } 111 112 } 113 114 // 定义大小相等的缓冲区,不需要再循环读 115 public static void readFile_4() 116 { 117 FileInputStream fis = null; 118 try 119 { 120 fis = new FileInputStream("f:\\fos.txt"); 121 // 数据太大时,不建议使用 122 byte[] btr = new byte[fis.available()]; 123 fis.read(btr); 124 System.out.println(new String(btr)); 125 } 126 catch(FileNotFoundException e) 127 { 128 e.printStackTrace(); 129 } 130 catch(Exception e) 131 { 132 e.printStackTrace(); 133 } 134 finally 135 { 136 if(null != fis) 137 try 138 { 139 fis.close(); 140 } catch (IOException e) 141 { 142 e.printStackTrace(); 143 } 144 } 145 } 146 147 // 写内容 148 public static void writeFile() 149 { 150 FileOutputStream fos = null; 151 try 152 { 153 fos = new FileOutputStream("f:\\fos.txt"); 154 // 要写入的内容 155 String str = "asdfghj"; 156 // 将字符串转换成字节数组 157 byte[] btr = str.getBytes(); 158 // 写入内容,不刷新不关闭的情况下也可以写入文件,因为写的是字节,不需要缓冲,所以可以直接写入 159 // 但是资源关闭还是必须的 160 fos.write(btr); 161 162 } catch (FileNotFoundException e) 163 { 164 e.printStackTrace(); 165 } catch (IOException e) 166 { 167 e.printStackTrace(); 168 } finally 169 { 170 if (null != fos) 171 try 172 { 173 fos.close(); 174 } catch (IOException e) 175 { 176 e.printStackTrace(); 177 } 178 } 179 180 } 181 }
1 /** 2 * 功能:复制图片 3 */ 4 package IO; 5 6 import java.io.FileInputStream; 7 import java.io.FileNotFoundException; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 11 public class FileStreamDemo2 12 { 13 public static void main(String[] args) throws Exception 14 { 15 FileInputStream fis = null; 16 FileOutputStream fos = null; 17 18 try 19 { 20 fis = new FileInputStream("f:\\1.jpg"); 21 fos = new FileOutputStream("f:\\2.jpg"); 22 23 byte[] btr = new byte[1024]; 24 int len = 0; 25 26 while ((len = fis.read(btr)) != -1) 27 { 28 fos.write(btr,0,len); 29 } 30 } catch (FileNotFoundException e) 31 { 32 throw new Exception("The file is null"); 33 } catch (IOException e1) 34 { 35 throw new Exception("Failed to read or write file"); 36 } finally 37 { 38 if(null != fis) 39 try 40 { 41 fis.close(); 42 } catch (IOException e) 43 { 44 e.printStackTrace(); 45 } 46 if (null != fos) 47 try 48 { 49 fos.close(); 50 } catch (IOException e) 51 { 52 e.printStackTrace(); 53 } 54 55 } 56 } 57 }
1 /** 2 * 功能;多媒体文件复制(视频、音乐) 3 */ 4 package IO; 5 6 import java.io.BufferedInputStream; 7 import java.io.BufferedOutputStream; 8 import java.io.FileInputStream; 9 import java.io.FileNotFoundException; 10 import java.io.FileOutputStream; 11 import java.io.IOException; 12 13 public class FileStreamDemo3 14 { 15 public static void main(String[] args) 16 { 17 copy_1(); 18 } 19 20 public static void copy_1() 21 { 22 FileInputStream fis = null; 23 FileOutputStream fos = null; 24 BufferedInputStream bfis = null; 25 BufferedOutputStream bfos = null; 26 try 27 { 28 fis = new FileInputStream("f:\\1.avi"); 29 bfis = new BufferedInputStream(fis); 30 fos = new FileOutputStream("f:\\2.avi"); 31 bfos = new BufferedOutputStream(fos); 32 33 // BufferedInputStream bfis = new BufferedInputStream(new FileInputStream("f:\\1.avi")); 34 // 不需要再定义用于缓冲的字节数组 35 int len = 0; 36 37 while ((len = bfis.read()) != -1) 38 { 39 bfos.write(len); 40 } 41 } catch (FileNotFoundException e) 42 { 43 e.printStackTrace(); 44 } catch (IOException e) 45 { 46 e.printStackTrace(); 47 } finally 48 { 49 if (null != bfos) 50 try 51 { 52 bfos.close(); 53 } catch (IOException e) 54 { 55 e.printStackTrace(); 56 } 57 if (null != fos) 58 try 59 { 60 fos.close(); 61 } catch (IOException e) 62 { 63 e.printStackTrace(); 64 } 65 if (null != bfis) 66 try 67 { 68 bfis.close(); 69 } catch (IOException e) 70 { 71 e.printStackTrace(); 72 } 73 if (null != fis) 74 try 75 { 76 fis.close(); 77 } catch (IOException e) 78 { 79 e.printStackTrace(); 80 } 81 } 82 } 83 }