一、缓存流
以介质是硬盘为例子说明,字节流和字符流的缺点:
每次读写的时候,都会访问硬盘,如果读写频率比较高的时候,性能不佳。为了解决问题,采用缓存流。
缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中区读取。
缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去,按照这种方式,就不会像字节流,字符流那样每次写一个字节都访问硬盘,减少了I/O操作。
1、使用缓存流读取数据
BufferedReader缓存字符输入流,可以一次读取一行数据

package stream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class TestStream{ public static void main(String[] args){ File f=new File("d/source/LOL.exe"); try(FileReader fr=new FileReader(f);BufferedReader br=new BufferedReader(fr);){ while(true){ String line=br.readLine();//一次读一行。 if(line==null)break; System.out.println(line); } }catch(IOException e){ e.printStackTrace(); } } }
2、使用缓存流写入数据
PrintWriter缓存字符输出流,可以一次写出一行数据

package stream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class TestStream{ public static void main(String[] args){ File f=new File("d/source/LOL.exe"); try(FileWriter fw=new FileWriter(f);PrintWriter pw=new PrintWriter(fw);){ { pw.println("hello world"); pw.println("hello kitty"); } }catch(IOException e){ e.printStackTrace(); } } }
3、使用flush
有时候,需要立即把数据写入到硬盘,而不是等缓存满了才写进去,这时候就要用flush。

package stream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class TestStream{ public static void main(String[] args){ File f=new file("d/source/LOL.exe"); //创建文件字符流 //缓存流必须建立在一个存在的流的基础上 try(FileWriter fr=new FileWriter(f);PrintWriter pw=new PrintWriter(fr);){ //向文件LOL.exe中写入三行语句。 pw.println("hello world"); //强制把缓存中的数据写入硬盘,无论缓存是否已满 pw.flush(); pw.println("I love play lol"); pw.flush(); pw.println("I love play dota"); pw.flush(); }catch(IOException e){ e.printStackTrace(); } } }
二、数据流
数据输入流:DataInputStream
数据输出流:DataOutputStream
数据流的方法:writeUTF(),readUTF()可以进行数据的格式化顺序读写
要用DataInputStream读取一个文件,这个文件必须由DataOutStream写出的,不然会抛出EOFException异常。也就是说这两个是成对出现的

package stream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestStream{ public static void main(String[] args){ write();//先写入 read();//在读取 } private static void read(){ File f=new File("d:/source/LOL.exe"); try( FileInputStream fis=new FileInputStream(f); DataInputStream dis=new DataInputStream(fis); ){ //然后在读取刚才写入到lol.exe文件里的东西。 boolean b=dis.readBoolean(); int i=dis.readInt(); String str=dis.readUTF(); System.out.println("读取到布尔值:"+b); System.out.println("读取到整数:"+i); System.out.println("读取到字符串"+str); }catch(IOException e){ e.printStackTrace(); } } private static void write(){ File f=new File("d:/source/LOL.exe"); try( FileOutStream fos=new FileOutputStream(f); DataOutStream dos=new DataOutStream(fos); ){ //把布尔型,整型,字符型这三个写到lol.exe文件里去 dos.writeBoolean(true); dos.writeInt(300); dos.writeUTF("hello world"); }catch(IOException e){ e.printStackTrace(); } } }
三、对象流
可以直接把一个对象以流的形式传输给其他的介质,比如硬盘,一个对象以流的形式进行传输,叫做序列化。
该对象所对应的类,必须是实现Serializable接口
首先序列化一个实体类Hero

package stream; import java.io.Serializable; public class Hero implements Serializable{ //表示这个类当前的版本,如果有了变化,比如添加了新的属性,就要修改这个版本号 private static final long serialVersionUID=1L; private String name; private float hp; }
如果要把Hero对象直接保存在文件上,必须让Hero类实现Serializable接口
首先要创建对象输出流,也就是写入对象到流,首先创建一个文件写入流FileOutputStream对象,然后在创建一个对象写入流ObjectOutputStream对象,把文件写入流传到对象写入流中。写入操作,利用ObjectOutputStream的writeObject()方法进行写入。同样读取操作,还是要先创建文件读取流FileInputStream对象,然后在创建一个对象读取流ObjectInputStream对象,把文件读取流对象传到对象读取流中。然后执行对象读取流的readObject()方法进行读取。

package stream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class TestStream{ public static void main(String[] args){ //创建一个Hero对象 //然后把Hero对象直接保存在文件上,必须Hero类实现Serializable接口 Hero h=new Hero(); h.name="Teemo"; h.hp=90.0; //准备一个文件用于保存新创建的Hero对象 File f=new File("d:/Teemo.lol"); try( //创建对象输出流(也就是写入) FileOutputStream fos=new FileOutputStream(f); ObjectOutputStream oos=new ObjectOutputStream(fos); //创建对象输入流(也就是读取) FileInputStream fis=new FileInputStream(f); ObjectInputStream ois=new ObjectInputStream(fis); ){ oos.writeObject(h); Hero h2=(Hero)ois.readObject(); System.out.println(h2.name); System.out.println(h2.hp); }catch(IOException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } } }
四、控制台的输入输出
控制台输出数据:System.out
控制台输入数据:System.in
利用System.in进行控制台写入。

package stream; import java.io.IOException; import java.io.InputStream; publc class TestStream{ public static void main(String[] args){ //控制台输入 try(InputStream is=System.in;){ while(true){ int i=is.read(); System.out.println(i); } }catch(IOException e){ e.printStackTrace(); } } }
利用Scanner进行逐行读取

package stream; import java.util.Scanner; public class TestStream{ public class void main(String[] args){ //使用Scanner进行逐行读取。 Scanner s=new Scanner(System.in); while(true){ String strLine=s.nextLine(); System.out.pirntln(strLine); } } }