java--IO流之字节流、字符流
一、字节流:
IO异常的处理
代码实现:
1 public class FileOutputStreamDemo3 { 2 public static void main(String[] args) { 3 File file = new File("c:\\file.txt"); 4 //定义FileOutputStream的引用 5 FileOutputStream fos = null; 6 try { 7 //创建FileOutputStream对象 8 fos = new FileOutputStream(file); 9 //写出数据 10 fos.write("abcde".getBytes()); 11 } catch (IOException e) { 12 System.out.println(e.toString() + "----"); 13 throw new RuntimeException("文件写入失败,重试"); 14 15 } finally { 16 //一定要判断fos是否为null,只有不为null时,才可以关闭资源 17 if (fos != null) { 18 try { 19 fos.close(); 20 } catch (IOException e) { 21 throw new RuntimeException("关闭资源失败"); 22 } 23 } 24 } 25 } 26 }
1、字节输出流OutputStream
OutputStream此抽象类,是表示输出字节流的所有类的超类。操作的数据都是字节,定义了输出字节流的基本共性功能方法。
输出流中定义都是写write方法,如下图:
OutputStream有很多子类,其中子类FileOutputStream可用来写入数据到文件。
FileOutputStream类,即文件输出流,是用于将数据写入 File的输出流。
关系
构造方法
代码实现:
public static void main(String[] args) throws IOException { //FileOutputStream的构造方法:如果文件存在,则覆盖,如果不存在,则创建 // \r\n 换行 FileOutputStream fos=new FileOutputStream("x:\\test\\bian.txt",true);//续写 /*fos.write(49); fos.write(48); fos.write(48);*/ /*byte[] bytes={-65,-66,-67,-68}; fos.write(bytes,1,2);*/ fos.write("xuezhiqian\r\n".getBytes()); //字符串转字节 /*new String(bytes);*/ //字节转字符串 fos.close(); }
2、字节输入流InputStream
常用方法:
FileInputStream类
构造方法:
FileInputStream类读取数据read方法
代码实现:
1 public static void main(String[] args) throws IOException { 2 FileInputStream fis=new FileInputStream("x:\\test\\test.txt"); 3 int len=0; 4 while((len=fis.read())!=-1){ 5 System.out.println((char)len);//转字符 6 } 7 /*int a=fis.read(); 8 System.out.println((char)a); 9 int b=fis.read(); 10 System.out.println((char)b); 11 int c=fis.read(); 12 System.out.println((char)c); 13 int d=fis.read(); 14 System.out.println((char)d); 15 int e=fis.read(); 16 System.out.println((char)e); 17 int f=fis.read(); 18 System.out.println((char)f);*/ 19 /*char ch=97; 20 System.out.println(ch);*/ 21 fis.close(); 22 } 23 }
读取数据read(byte[])方法
代码实现:
1 public class InputStreamDemo2 { 2 public static void main(String[] args) throws IOException { 3 FileInputStream fis=new FileInputStream("x:\\test\\test.txt"); 4 byte[] bytes=new byte[2]; 5 int len=0; 6 while((len=fis.read(bytes))!=-1){ 7 System.out.println(new String(bytes,0,len)); 8 } 9 /* //第一次读 10 int len=fis.read(bytes); 11 System.out.println(len); 12 System.out.println(new String(bytes)); 13 //第二次读 14 len=fis.read(bytes); 15 System.out.println(len); 16 System.out.println(new String(bytes)); 17 //第三次读 18 len=fis.read(bytes); 19 System.out.println(len); 20 System.out.println(new String(bytes)); 21 //第4次读 22 len=fis.read(bytes); 23 System.out.println(len); 24 System.out.println(new String(bytes));*/ 25 fis.close(); 26 } 27 28 }
字节流复制文件
代码实现:
public class CopyDemo { 2 public static void main(String[] args) throws IOException { 3 long time1=System.currentTimeMillis(); 4 //1.明确数据源(要复制哪个文件) 5 FileInputStream fis=new FileInputStream("C:\\Program Files\\java\\eclipse.zip"); 6 //2.明确目的地(要复制到哪个文件) 7 FileOutputStream fos=new FileOutputStream("x:\\test\\d\\java.txt"); 8 //3.复制 9 int len=0; 10 while((len=fis.read())!=-1){ 11 fos.write(len); 12 } 13 long time2=System.currentTimeMillis(); 14 System.out.println(time2-time1); 15 //4.释放资源 16 fis.close(); 17 fos.close(); 18 } 19 20 }
3、缓冲字节流
①写入数据到流中,字节缓冲输出流 BufferedOutputStream
②读取流中的数据,字节缓冲输入流 BufferedInputStream
它们的内部都包含了一个缓冲区,通过缓冲区读写,就可以提高了IO流的读写速度
字节缓冲输出流BufferedOutputStream
构造方法:
public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
代码实现:
1 //缓冲字节输出流 2 public static void method1() throws IOException{ 3 FileOutputStream fos=new FileOutputStream("e:\\test\\haha",true); 4 BufferedOutputStream bos=new BufferedOutputStream(fos); 5 //bos.write(100); 6 bos.write("你好啊".getBytes()); 7 bos.close(); 8 }
字节缓冲输入流 BufferedInputStream
构造方法:
public BufferedInputStream(InputStream in)
代码实现:
1 //缓冲字节输入流 2 public static void method2() throws IOException{ 3 FileInputStream fis=new FileInputStream("e:\\test\\haha"); 4 BufferedInputStream bis=new BufferedInputStream(fis); 5 int len=0; 6 while((len=bis.read())!=-1){ 7 System.out.print((char)len); 8 } 9 bis.close(); 10 }
对比字节流read(),字节流read(byte []),缓冲字节流read(),缓冲字节流read(byte [])它们的速度
1 //字节流read() 2 public static void method1() throws IOException{ 3 long time1=System.currentTimeMillis(); 4 FileInputStream fis=new FileInputStream("d:\\DW\\jdk\\javafx-src.zip"); 5 FileOutputStream fos=new FileOutputStream("e:\\test\\text\\haha1.zip"); 6 int len=0; 7 while((len=fis.read())!=-1){ 8 fos.write(len); 9 } 10 long time2=System.currentTimeMillis(); 11 System.out.println(time2-time1); 12 fis.close(); 13 fos.close(); 14 } 15 //字节流read(byte []) 16 public static void method2() throws IOException{ 17 long time1=System.currentTimeMillis(); 18 FileInputStream fis=new FileInputStream("d:\\DW\\jdk\\javafx-src.zip"); 19 FileOutputStream fos=new FileOutputStream("e:\\test\\text\\haha2.zip"); 20 int len=0; 21 byte[] bytes=new byte[1024]; 22 while((len=fis.read(bytes))!=-1){ 23 fos.write(bytes, 0, len); 24 } 25 long time2=System.currentTimeMillis(); 26 System.out.println(time2-time1); 27 fis.close(); 28 fos.close(); 29 } 30 //缓冲字节流read() 31 public static void method3() throws IOException{ 32 long time1=System.currentTimeMillis(); 33 FileInputStream fis=new FileInputStream("d:\\DW\\jdk\\javafx-src.zip"); 34 BufferedInputStream bis=new BufferedInputStream(fis); 35 FileOutputStream fos=new FileOutputStream("e:\\test\\text\\haha3.zip"); 36 BufferedOutputStream bos=new BufferedOutputStream(fos); 37 int len=0; 38 while((len=bis.read())!=-1){ 39 bos.write(len); 40 } 41 long time2=System.currentTimeMillis(); 42 System.out.println(time2-time1); 43 fis.close(); 44 fos.close(); 45 } 46 //缓冲字节流read(byte []) 47 public static void method4() throws IOException{ 48 long time1=System.currentTimeMillis(); 49 FileInputStream fis=new FileInputStream("d:\\DW\\jdk\\javafx-src.zip"); 50 BufferedInputStream bis=new BufferedInputStream(fis); 51 FileOutputStream fos=new FileOutputStream("e:\\test\\text\\haha4.zip"); 52 BufferedOutputStream bos=new BufferedOutputStream(fos); 53 int len=0; 54 byte[] bytes=new byte[1024]; 55 while((len=bis.read(bytes))!=-1){ 56 bos.write(bytes, 0, len); 57 } 58 long time2=System.currentTimeMillis(); 59 System.out.println(time2-time1); 60 fis.close(); 61 fos.close(); 62 }
结果:
速度总结:(慢——>快)
字节流read() < 缓冲字节流read() < 字节流read(byte []) < 缓冲字节流read(byte [])
二、字符流
字节流读取字符的问题
代码实现:
1 public class CharStreamDemo { 2 public static void main(String[] args) throws IOException { 3 //给文件中写中文 4 writeCNText(); 5 //读取文件中的中文 6 readCNText(); 7 } 8 //读取中文 9 public static void readCNText() throws IOException { 10 FileInputStream fis = new FileInputStream("c:\\cn.txt"); 11 int ch = 0; 12 while((ch = fis.read())!=-1){ 13 System.out.println(ch); 14 } 15 } 16 //写中文 17 public static void writeCNText() throws IOException { 18 FileOutputStream fos = new FileOutputStream("c:\\cn.txt"); 19 fos.write("欢迎你".getBytes()); 20 fos.close(); 21 } 22 }
1.字符输入流Reader
基础方法:
FileReader类
代码实现:
public class ReaderDemo { public static void main(String[] args) throws IOException { //通过字符数组的方式读 FileReader fr=new FileReader("x:\\test\\test.txt"); int len=0; char[] ch=new char[1024]; while((len=fr.read(ch))!=-1){ System.out.println(new String(ch,0,len)); } fr.close(); //method1(fr); } public static void method1(FileReader fr) throws IOException{ //通过一个字符一个字符的方法读 int len=0; while((len=fr.read())!=-1){ System.out.print((char)len); } fr.close(); } }
2.字符输入流writer
基础方法:
FileWriter类
构造方法:
字符流复制文件代码实现:
1 public class JpgCopy1 { 2 //字符流复制文件 3 public static void main(String[] args) throws IOException { 4 //1.明确数据源 5 FileReader fr=new FileReader("X:\\test\\img1.jpg"); 6 //2.明确目的地 7 FileWriter fw=new FileWriter("x:\\test\\a\\img1.jpg"); 8 //3.复制 9 int len=0; 10 char[] ch=new char[1024]; 11 while((len=fr.read(ch))!=-1){ 12 fw.write(ch, 0, len); 13 } 14 //4.释放资源 15 fr.close(); 16 fw.close(); 17 } 18 }
flush()和close()的区别
close是在关闭之前刷新一次
flush是一边存一边刷
代码实现:
1 public class WriterDemo { 2 public static void main(String[] args) throws IOException { 3 //写入中文字符 4 FileWriter fw=new FileWriter("x:\\test\\test.txt"); 5 fw.write("你好"); 6 fw.flush();//可刷新多次 7 //fw.close();//具有一次刷新功能 8 } 9 }
3.字符缓冲输出流 BufferedWriter
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
方法:newLine() 根据当前的系统,写入一个换行符
1 //缓冲字符输出流 2 //bw.newLine();换行可以实现平台无关性 3 //win 换行\r\n 4 //linux 换行\n 5 public static void method5() throws IOException{ 6 FileWriter fw=new FileWriter("E:\\test\\test.txt"); 7 BufferedWriter bw=new BufferedWriter(fw); 8 bw.write("你好吗".toCharArray());//字符转字符数组 9 bw.flush(); 10 bw.write("我很好"); 11 bw.newLine();//换行 12 bw.flush(); 13 bw.newLine(); 14 bw.write(100); 15 bw.close(); 16 }
4.字符缓冲输入流 BufferedReader
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
方法:readLine() 读取一个文本行,包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
代码实现:
public class BufferedReaderDemo { public static void main(String[] args) throws IOException { //1,创建流 FileReader fr=new FileReader("file.txt") BufferedReader in = new BufferedReader(fr); //2,读数据 //一次一个字符 //一次一个字符数组 //一次读取文本中一行的字符串内容 String line = null; while( (line = in.readLine()) != null ){ System.out.println(line); } //3,关闭流 in.close(); } }
使用字符缓冲流完成文本文件的复制
public class CopyTextFile { public static void main(String[] args) throws IOException { //1,指定数据源, 是数据源中读数据,采用输入流 BufferedReader in = new BufferedReader(new FileReader("file.txt")); //2,指定目的地,是把数据写入目的地,采用输出流 BufferedWriter out = new BufferedWriter(new FileWriter("copyFile.txt")); //3,读数据 String line = null; while ( (line = in.readLine()) != null ) { //4,写数据 out.write(line); //写入换行符号 out.newLine(); out.flush(); } //5,关闭流 out.close(); in.close(); } }
总结:流的操作规律
IO流中对象很多,解决问题(处理设备上的数据时)到底该用哪个对象呢?
把IO流进行了规律的总结(四个明确):
明确一:要操作的数据是数据源还是数据目的。
源:InputStream Reader
目的:OutputStream Writer
先根据需求明确要读,还是要写。
明确二:要操作的数据是字节还是文本呢?
源:
字节:InputStream
文本:Reader
目的:
字节:OutputStream
文本:Writer
已经明确到了具体的体系上。
明确三:明确数据所在的具体设备。
源设备:
硬盘:文件 File开头。
内存:数组,字符串。
键盘:System.in;
网络:Socket
目的设备:
硬盘:文件 File开头。
内存:数组,字符串。
屏幕:System.out
网络:Socket
完全可以明确具体要使用哪个流对象。
明确四:是否需要额外功能呢?
额外功能:
转换吗?转换流。InputStreamReader OutputStreamWriter
高效吗?缓冲区对象。BufferedXXX