1、IO流
处理设备之间的数据传输
字符流为了处理文字而存在,基于字节流,其中融合了编码表
1.1、Writer--------write,flush,close
java.util.FileWriter
FileWriter(String fileName)根据给定的文件名构造一个FileWriter对象
java.io.OutputStreamWriter
void write(String str, int off, int len)将数据写入流中
void flush()刷新流中的缓冲
void close()关闭此流,但要先刷新它
1 import java.io.FileWriter; 2 import java.io.IOException; 3 4 /* 5 * 字符流和字节流 6 * 7 * 字节流两个基类 8 * InputStream OutputStream 9 * 10 * 字符流两个基类 11 * Reader Writer 12 * 13 * 先学习一下字符流的特点 14 * 既然IO流是用于操作数据的 15 * 那么数据的最常见体现形式是文件 16 * 17 * 那么先以操作文件为主来演示 18 * 需求: 在硬盘上,创建一个文件并写入一些文字数据 19 * 20 * 找到一个专门用于操作文件的Writer子类对象,FileWriter。后缀名是父类名,前缀名是该流对象的功能 21 * */ 22 public class FileWriterDemo { 23 public static void main(String[] args) throws IOException{ 24 //创建一个FileWriter对象,该对象以被初始化就必须要明确被操作的文件 25 //而且该文件会被创建到制定目录下,如果该目录下已有同名文件,会被覆盖 26 //其实就是明确数据要存放的目的地 27 FileWriter fw = new FileWriter("demo.txt"); 28 29 //调用write方法,将字符串写入到流中 30 fw.write("abcde"); 31 32 //刷新流对象中的缓冲中的数据 33 // fw.flush(); 34 35 36 //关闭流资源,但是关闭之前会刷新一次内部缓冲数据 37 //将数据刷到目的地中,和flush的区别在于 38 //和flush区别,flush刷新后,流可以继续使用,close刷新后会将流关闭 39 fw.close(); 40 } 41 42 }
运行结果
1.2、异常处理机制
注意close放入finally,但是也需要排除流创建失败带来的空指针异常,因此需要一个判断
1 package learn; 2 3 import java.io.FileWriter; 4 import java.io.IOException; 5 6 /*IO异常的处理方式 7 * 8 * */ 9 public class FileWriterDemo2 { 10 public static void main(String[] args) { 11 FileWriter fw =null;//对象的建立和引用的挂钩分开写 12 try 13 { 14 //fw创建失败则不可能添加数据,故放在一个try中 15 fw = new FileWriter("demo.txt"); 16 fw.write("abcdefg"); 17 18 } 19 catch(IOException e) 20 { 21 System.out.println(e.toString()); 22 } 23 //必须要关闭流,所以必须写finally, 24 //但是因可能出现没流建立成功,没流能关闭,所以也将关闭写作异常 25 //finally的执行也需要 fw不为空时才可以 26 finally 27 { 28 try 29 { 30 if(fw!=null) 31 fw.close(); 32 } 33 catch(IOException e) 34 { 35 System.out.println(e.toString()); 36 } 37 38 } 39 40 } 41 }
运行结果
1.3、文件的续写
java.io.FileWriter
FileWriter(String fileName, boolean append)根据指定的文件名以及指示是否附加写入数据的boolean值得来构造FileWriter对象。true则在末尾处添加
windows中的换行符为/r/n,因而只写/n得到的是黑块
1 package learn; 2 3 import java.io.FileWriter; 4 import java.io.IOException; 5 6 /* 7 * 演示对已有文件的数据续写 8 * */ 9 public class FileWriterDemo3 { 10 public static void main(String[] args) throws IOException{ 11 //传递一个true参数,代表不覆盖已有的文件,并在已有文件末尾处进行数据续写 12 FileWriter fw= new FileWriter("demo.txt",true); 13 fw.write("ha\r\nha"); 14 fw.close(); 15 } 16 }
运行结果
2.1、Reader
文本读取方式一
java.io.Reader
int read() 读取单个字符,一直读下去的话,末尾返回值为-1
1 package learn; 2 3 import java.io.FileReader; 4 import java.io.IOException; 5 6 public class FileReadDemo { 7 public static void main(String[] args) throws IOException{ 8 //创建一个文件读取流对象,和指定名称的文件相关联 9 //要保证文件是已经存在的,如果不存在,会发生异常FileNotFoundException 10 FileReader fr = new FileReader("demo.txt"); 11 //调用读取流对象的read方法 12 //read方法一次读一个字符,且会自动往下读 13 int ch = 0; 14 while((ch=fr.read())!=-1) 15 { 16 System.out.println((char)ch); 17 } 18 fr.close(); 19 } 20 }
运行结果
2.2、文本读取方式二
先创建一个数组,读一个存一个,读完了,输出。
java.lang.String
String(int[] codePoints, int offset, int count)分配一个新的String, 它包含Unicode代码点数组参数一个子数组的字符
offset初始偏移量, count长度,(长度即为下例中的num)
1 package learn; 2 3 import java.io.FileReader; 4 import java.io.IOException; 5 6 public class FileReadDemo2 { 7 public static void main(String[] args) throws IOException{ 8 FileReader fr = new FileReader("demo.txt"); 9 //定义一个字符数组,用于存储读到字符 10 //该read(char[])返回的是读到字符个数 11 //通常定义new char[1024]; 12 //创建字符数组,大小为3 13 char[] buf = new char[3]; 14 int num = 0; 15 //读一个存一下 16 while((num = fr.read(buf))!=-1) 17 { 18 System.out.println(new String(buf,0,num)); 19 } 20 // int num = fr.read(buf); 21 // System.out.println("num="+num+"..."+new String(buf)); 22 fr.close(); 23 } 24 }
运行结果
2.2.1、练习
当文件内容超过了1024,才会出现println的换行
1 package Test; 2 3 import java.io.FileReader; 4 import java.io.IOException; 5 6 /*读取一个.java文件,并打印在控制台上*/ 7 public class FileReaderTest { 8 public static void main(String[] args) throws IOException{ 9 FileReader fr = new FileReader("FileReadDemo.java"); 10 char[] buf = new char[1024]; 11 int num = 0; 12 while((num = fr.read(buf))!=-1) 13 { 14 System.out.println(new String(buf,0,num)); 15 } 16 fr.close(); 17 } 18 }
运行结果
2.3、copy
copy2更好
思路:有了存放的地方,先读,临时存放下,再一起写入
1 package Test; 2 3 import java.io.FileReader; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 7 /* 8 * 将C盘一个文本文件复制到D盘 9 * 复制的原理: 10 * 其实就是将C盘下的文件数据存储到D盘的一个文件中 11 * 12 * 步骤: 13 * 1、在D盘创建文件。用于存储C盘文件中的数据 14 * 2、定义读取流和C盘文件关联 15 * 3、通过不断你的读写完成数据存储 16 * 4、关闭资源 17 * */ 18 public class CopyText { 19 public static void main(String[] args) throws IOException { 20 copy2(); 21 } 22 //从c盘读一个字符写一个字符 23 public static void copy1 ()throws IOException 24 { 25 //创建目的地 26 FileWriter fw = new FileWriter("RuntimeDemo_copy.txt"); 27 //与已有文件关联 28 FileReader fr = new FileReader("FileReadDemo.java"); 29 int ch = 0; 30 //有一个字符写一次 31 while((ch=fr.read())!=-1) 32 { 33 fw.write(ch); 34 } 35 fw.close(); 36 fr.close(); 37 38 } 39 public static void copy2() 40 { 41 FileWriter fw = null; 42 FileReader fr = null; 43 try 44 { 45 fw = new FileWriter("SystemDe_copy2.txt"); 46 fr = new FileReader("FileReadDemo.java"); 47 char[] buf= new char[1024]; 48 int len = 0; 49 while((len=fr.read(buf))!=-1) 50 { 51 fw.write(buf,0,len); 52 } 53 } 54 catch(IOException e) 55 { 56 throw new RuntimeException("读写失败"); 57 } 58 finally 59 { 60 if(fr!=null) 61 try 62 { 63 fr.close(); 64 } 65 catch(IOException e) 66 { 67 } 68 if(fw!=null) 69 try 70 { 71 fw.close(); 72 } 73 catch(IOException e) 74 { 75 } 76 } 77 } 78 }
运行结果
3、字符流的缓冲区
3.1、BufferedWriter
java.io.BufferedWriter
void newLine();写入一个换行符,通用于各操作系统,在win中换成\r\n,在linux中换成\n
因为有流才会有缓冲区,故其构造函数都带有参数
1 package learn; 2 3 import java.io.BufferedWriter; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 7 /* 8 * 缓冲区的出现时为了提高流的操作效率而出现的 9 * 所以在创建缓冲区之前,必须要先有流对象 10 * 该缓冲区中提供了跨平台的换行符newLine(); 11 * */ 12 public class BufferedWriterDemo { 13 public static void main(String[] args)throws IOException { 14 //创建字符写入流对象 15 FileWriter fw = new FileWriter("buf.txt"); 16 //为了提高字符写入流效率,加入了缓冲技术 17 //只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可 18 BufferedWriter bufw = new BufferedWriter(fw); 19 for(int x=1;x<5;x++) 20 { 21 bufw.write("abcd"+x); 22 bufw.newLine(); 23 bufw.flush(); 24 } 25 26 //记住,只要用到缓冲区就要记得刷新 27 //其实关闭缓冲区就是在关闭缓冲区中的流对象 28 bufw.flush(); 29 bufw.close(); 30 31 } 32 }
运行结果
3.2、BufferedReader
java.io.BufferedReader
String readLine()读取文本下一行
1 package learn; 2 /* 3 * 字符流取流缓冲区: 4 * 该缓冲区提供了一个一次读一行的方法readLine, 方便于对文本数据的获取。 5 * 当返回null时,表示读到文件末尾。 6 * */ 7 import java.io.BufferedReader; 8 import java.io.FileReader; 9 import java.io.IOException; 10 11 public class BufferedReaderDemo { 12 public static void main(String[] args) throws IOException{ 13 //创建一个读取流对象和文件相关联 14 FileReader fr = new FileReader("buf.txt"); 15 //为了提高效率,加入缓冲技术,将字符读取流对象作为参数传递给缓冲对象的构造函数 16 BufferedReader bufr = new BufferedReader(fr); 17 String line = null; 18 while((line=bufr.readLine())!=null) 19 { 20 System.out.println(line); 21 } 22 // String s1 = bufr.readLine(); 23 // System.out.println("s1:"+s1); 24 bufr.close(); 25 26 } 27 }
运行结果
3.2.2练习 通过缓冲区复制文件
readLine不返回回车符,即会卡在一行所以在write时须加newLine();
1 package learn; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.FileReader; 6 import java.io.FileWriter; 7 import java.io.IOException; 8 9 /* 10 * 通过缓冲区复制一个java文件 11 * readLine不返回车符 12 * */ 13 public class CopyTextByBuf { 14 public static void main(String[] args) { 15 BufferedReader bufr = null; 16 BufferedWriter bufw = null; 17 try 18 { 19 bufr = new BufferedReader(new FileReader("FileReadDemo.java")); 20 bufw = new BufferedWriter(new FileWriter("bufWriter_Copy.txt")); 21 String line =null; 22 while((line=bufr.readLine())!=null) 23 { 24 bufw.write(line); 25 //不加就在一行 26 bufw.newLine(); 27 bufw.flush(); 28 } 29 } 30 catch(IOException e) 31 { 32 throw new RuntimeException("读写失败"); 33 } 34 finally 35 { 36 try 37 { 38 if(bufr!=null) 39 bufr.close(); 40 } 41 catch(Exception e) 42 { 43 throw new RuntimeException("读取关闭失败"); 44 } 45 try 46 { 47 if(bufw!=null) 48 bufr.close(); 49 } 50 catch(Exception e) 51 { 52 throw new RuntimeException("写入关闭失败"); 53 } 54 } 55 } 56 }
运行结果
3.3、