1.介绍
2.字符流在实际开发过程中经常会用到数据的输入/输出操作,本篇博客着重分析一下,java中经经常使用到的有关IO操作的类。而在java中能够将经常使用的流分为两个部分:字节流和字符流。
1.流的抽象基类
字节流 字符流 输入流 InputStream Reader 输出流 OutPutStream Writer
正如上图表格所看到的。字符和字节流都有自己的基类,其余的都是继承基类的扩展流的操作。以下会着重的解说一下。(仅仅要会了字符流,字节流与其操作一样,仅仅只是操作的文件类型不一致而已)
专门用于读写文本数据。凡是能够用记事本打开的文件比如txt、java、html都数据字符流的操作范围
1.字符输出流——FileWriter
字符输出流一般应用的是FileWriter,然后调用其构造函数,传递字符串的文件名称,将字符写在这个文件里。其次调用父类方法Write(String str)写字符串。在这里须要注意的是字符流写数据,不会直接写在目的文件里。而是写在内存中,必须走一个方法,刷新。将内存中的数据刷新到目的文件里,字符流写数据必须刷新。一般调用的是Void Flush()方法,最后用完后须要关闭流对象。
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package com.IO; import java.io.FileWriter; import java.io.IOException; public class FileWriterDemo1 { public static void main(String[] args) { FileWriter fw = null; try { //採用这样的形式的话。每次都会覆盖曾经的数据信息 // fw=new FileWriter("c:\\exception.txt"); //採用这样的构造器的话,将会採用追加的形式加入数据。 //查询本机默认编码表示GBK fw=new FileWriter("c:\\exception.txt",true); fw.write("abd"); fw.flush(); fw.write("弄H啊哦吗"); fw.flush(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("文件写入失败"); }finally{ try { //必须在这里进行推断否则,报错。可能会报空指针的异常信息。if(fw!=null){ fw.close(); } } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("关闭资源失败"); } } } } </span></span>
FileWriter写文本文件操作例如以下
单个字符的形式。调用的父类Write(int c)方法
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.Io.iostream; import java.io.*; class FileWriterDemo1 { public static void main(String[] args) { //创建输出流对象 FileWriter fw = null; try{ fw = new FileWriter("c:\\1.txt"); fw.write("abc"); fw.flush(); fw.write("adb"); //将内存中的数据刷新到文件里 fw.flush(); }catch(IOException e){ e.printStackTrace(); throw new RuntimeException("写入数据失败"); }finally{ try{ if(fw!=null) fw.close(); }catch(IOException e){ e.printStackTrace(); throw new RuntimeException("关闭流对象失败"); } } } } </span></span>字符数组的形式,调用的方法例如以下
~write(char[] ch)传递整个字符数组
~write(char[] ch,int off,int len)写数组的一部分,off開始下标。len个数
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.IO.iostream; /* * FileWriter以数组的形式写入文件 * */ import java.io.*; public class FileWriterDemo2 { public static void main(String[] args) throws IOException { //调用此输出流的构造函数,将会以追加的形式写入到文件内容中 FileWriter fw = new FileWriter("c:\\demo.txt",true); fw.write(97); char[] ch= {'a','b','c'}; fw.write(ch,1,1); fw.write("sefser"); fw.flush(); fw.close(); } } </span></span>
注意,假设要想文件里追加写入内容,而不是覆盖原来的内容的话。仅仅需在创建输入流对象的时候,调用其FileWriter(String fileName, boolean append)构造方法就可以
2.字符输入流
字符输入流一般应用的是FileReader读取文本文件。然后调用其构造方法,创建输入流对象。传递字符文件名称,比如new FileReader('文件名称')。读取一个字符 int read()方法。每次仅仅读取一个字符,然后指定的read()方法,会自己主动的向后读取一个,读到末尾的时候,将会返回-1
读取单个字符
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.IO.iostream; /* * 採用字符输入流对象。进行读取文件操作 */ import java.io.*; public class FileReaderDemo { public static void main(String[] args) throws IOException{ //创建输入流对象 FileReader fr = new FileReader("c:\\demo.txt"); //调用Read方法。每次仅仅读取一个字符操作 int x = 0; while((x = fr.read())!=-1){ System.out.print((char)x); } fr.close(); } } </span></span>
读取字符数组操作
int read(char[] cbuf):读取方法,传递字符数组。返回值int代表有效读取的字符个数,此方法读取效率高
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.itcast.iostream; /* * 採用字符输入流对象进行字符数组的读取 */ import java.io.*; public class FileReaderDemo1 { public static void main(String[] args) throws IOException{ FileReader fr = new FileReader("c:\\demo.txt"); //创建一个字符数组 char[] ch = new char[1024];//通常是1024的倍数 int x = 0 ; while(( x = fr.read(ch))!=-1){ //String(char[] value, int offset, int count) System.out.print(new String(ch,0,x)); } fr.close(); } } </span></span>
拷贝文件操作
利用字符流的输入和输出流,来操作文件的复制功能
第一种方式,读一个字符,写一个字符
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.IO.iostream; /* * 採用字符流来实现复制的功能 */ import java.io.*; public class CopyText { public static void main(String[] args) { long start = System.currentTimeMillis(); //创建字符输入和输出流的对象 FileReader fr = null; FileWriter fw = null; try{ //分别调用其构造函数 fr = new FileReader("c:\\demo.txt"); fw = new FileWriter("d:\\demo.txt"); //定义变量来报错单个字符读取的值 int len = 0 ; while((len = fr.read())!=-1){ fw.write(len); fw.flush(); } }catch(IOException e){ throw new RuntimeException("复制失败"); }finally{ try{ if(fw!=null) fw.close(); }catch(IOException e){ throw new RuntimeException("关闭写入流失败"); }finally{ try{ if(fr!=null) fr.close(); }catch(IOException e){ throw new RuntimeException("关闭输入流失败"); } } } long end = System.currentTimeMillis(); System.out.println(end - start); } } </span></span>
另外一种方法:读一个字符数组。写一个字符数组<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package cn.IO.iostream; /* *採用输入和输出流完毕复制的功能操作 */ import java.io.*; public class CopyText2 { public static void main(String[] args) { long start = System.currentTimeMillis(); //分别创建字符输入和输出流对象 FileReader fr = null; FileWriter fw = null; try{ //分别调用其构造函数实例化 fr = new FileReader("c:\\e.html"); fw = new FileWriter("d:\\1.html"); //定义要读取的字符数组 char[] ch = new char[1024]; int len = 0 ; while((len = fr.read(ch))!=-1){ fw.write(ch,0,len); fw.flush(); } }catch(IOException e){ throw new RuntimeException("复制失败"); }finally{ try{ if(fw!=null) fw.close(); }catch(IOException e){ throw new RuntimeException("关闭输出流失败"); }finally{ try{ if(fr!=null) fr.close(); }catch(IOException e){ throw new RuntimeException("关闭输入流失败"); } } } long end = System.currentTimeMillis(); System.out.println(end - start); } } </span></span>注意:利用读取字符数组的形式,效率会快非常多
3.缓冲流
在读写的时候。也能够採取缓冲流的形式对字符或者字节进行缓冲,从而实现字符、数组和行的高效读写操作。
字符 字节 缓冲输入流 BufferedReader BufferedInputStream 缓冲输出流 BufferedWriter BufferedOutputStream
主要是在缓冲流中能够採取读取一行方式。来操作源文件。
全部的操作都是一致的,都是通过构造方法的形式,传递字符或者字节流,比如BufferedReader(Reader r),来传递进去FileReader,通过String ReadLine()方法来读取文件的一行,当读到文件末尾的时候,将返回null值
<span style="font-family:SimSun;font-size:18px;">package com.IO; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; /* * 字符输入流。BufferedReader,读取文本一行的功能 */ public class BufferedReaderDemo { public static void main(String[] args) throws IOException { //建立字符输入流缓冲区对象,传递字符输入对象 BufferedReader bfr=new BufferedReader(new FileReader("c:\\1.txt")); //開始读取文本一行。返回string String line=bfr.readLine(); System.out.println(line); } } </span>其余的BufferedInputStream、BufferedOutPutStream、BufferedReader、BufferedWriter使用方法一致。參照上面写法就可以。
採用缓冲流实现文件复制的效果。
<span style="font-family:SimSun;font-size:18px;">package com.IO; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import javax.management.RuntimeErrorException; /* * 利用字符流缓冲区来赋值 * 读写行,写换行 */ public class CopyTest2 { public static void main(String[] args) { // 匿名对象的形式。创建流对象和缓存去对象 BufferedReader bfr = null; BufferedWriter brw = null; try { bfr = new BufferedReader(new FileReader("c:\\1.txt")); brw = new BufferedWriter(new FileWriter("c:\\2.txt")); // 读取一行,写一行,写换行 String line = null; while ((line = bfr.readLine()) != null) { brw.write(line); //进行换行的功能 brw.newLine(); brw.flush(); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("复制失败"); }finally{ try { if(bfr!=null){ bfr.close(); } } catch (IOException e2) { throw new RuntimeException("写入关闭失败"); }finally{ try { if(brw!=null){ brw.close(); } } catch (IOException e3) { throw new RuntimeException("读入关闭失败"); } } } } } </span>
4.转换流
Java中的转换流一般有两个各自是,OutPutStreamWriter、InputStreamReader。是字符流通向字节流的桥梁。
正如上图所看到的,通过缓冲流就能够把字节流转换成为字符流来处理,通过缓冲区一包装,就能够读取行的操作了。
<span style="font-family:SimSun;font-size:18px;">package com.IO; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class TranseDemo3 { public static void main(String[] args) throws IOException { /*//控制台输入的字节流 InputStream in=new FileInputStream("c:\\1.java"); //创建转换流对象,传递字节输入流 InputStreamReader isr=new InputStreamReader(in); //既然已经将in转换成了字符流isr,能够使用字符流缓冲区对象BufferedReader,行读取 BufferedReader bfr=new BufferedReader(isr); OutputStream out=System.out; OutputStreamWriter osw=new OutputStreamWriter(out); BufferedWriter bfw=new BufferedWriter(osw);*/ BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in)); BufferedWriter brw=new BufferedWriter(new OutputStreamWriter(System.out)); String line=null; while ((line=bfr.readLine())!=null) { brw.write(line); brw.flush(); brw.newLine(); } brw.close(); bfr.close(); } } </span>