IO流主要用于硬板、内存、键盘等处理设备上得数据操作,根据处理数据的数据类型的不同可以分为:字节流(抽象基类为InputStream和OutputStream)和字符流(抽象基类为Reader和Writer)。根据流向不同,可以分为:输入流和输出流。一般探讨IO流时,是按数据类型来分的。
IO流的分类:
流向:
输入流 (读取数据)
输出流 (写出数据)
数据类型:
字节流
字节输入流(读取数据) InputStream
字节输出流 (写出数据)OutputStream
字符流
字符输入流 (读取数据) Reader
字符输出流 (写出数据) Writer
字符流和字节流的主要区别:
1.字节流读取的时候,读到一个字节就返回一个字节; 字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。
2.字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。
一、字节流:
1、字节输出流:FileOutputStream
构造方法:
public FileOutputStream(File file)
public FileOutputStream(String name)
public FileOutputStream(String name,boolean append):当append设为true,可以在原有文件上追加数据
Write方法:
public void write(int b) :写一个字节到文件输出流
public void write(byte[] b) :从byte[]数组中写b.length个字节到文件输出流
public void write(byte[] b, int off, int len) :从索引为off开始,写len个长度的字节到文件输出流
void createFileOutputStream() throws IOException { FileOutputStream fos=new FileOutputStream("a.txt"); fos.write("Hello World".getBytes()); byte[] by={97,98,99,100}; fos.write(by); byte[] by2={101,102,103,104,105}; fos.write(by2,1,3); fos.close(); }
最后给出加入了异常处理的字节输出流的写法:
FileOutputStream fos= null; try { fos = new FileOutputStream("a.txt"); fos.write("Hello World".getBytes()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if(fos!=null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } }
2、字节输入流:FileInputStream
构造方法:
public FileInputStream(File file)
public FileInputStream(String name)
读取方法:
public int read() :从输入流中读取一个字节,如果已到达文件末尾,则返回-1;
public int read(byte[] b) :从输入流中将最多 b.length
个字节的数据读入一个 byte 数组中。如果因为已经到达文件末尾而没有更多的数据,则返回 -1
。
以下是代码示例:
//一次读取一个字节 FileInputStream fis=new FileInputStream("a.txt"); int b=0; while ((b=fis.read())!=-1){ System.out.print((char)b); } fis.close(); //一次读取一个字节数组 FileInputStream fis2=new FileInputStream("a.txt"); byte[] by=new byte[1024]; int len=0; while ((len=fis2.read(by))!=-1){ System.out.print(new String(by,0,len)); } fis2.close();
小提示:计算机是如何识别什么时候将两个字节转成中文的呢?
因为中文的第一个字节肯定是负数,第二个字节不论正负,都没有影响。
3、字节缓冲输出流:BufferedOutputStream
该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
//字节缓冲输出流写出文件 BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("a.txt")); bos.write("Hello World".getBytes()); bos.close();
4、字节缓存输入流:BufferedInputStream
在创建 BufferedInputStream
时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。
//字节缓冲输入流读取文件 BufferedInputStream bis=new BufferedInputStream(new FileInputStream("a.txt")); byte[] bytes=new byte[1024]; int len=0; while ((len=bis.read(bytes))!=-1){ System.out.print(new String(bytes,0,len)); } bis.close();
二、字符流
1、字符输出流 OutputStreamWriter、FileWriter
字符流=字节流+编码。
a、OutputStreamWriter
构造方法:
OutputStreamWriter(OutputStream out) :根据默认编码把字节流的数据转换为字符流
OutputStreamWriter(OutputStream out,String charsetName) :根据指定的编码把字节流的数据转换为字符流
b、FileWriter--------FileWriter继承自OutputStreamWriter
构造方法
FileWriter(File file)
FileWriter(String name)
用法:
//用OutputStreamWriter写出 OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("a.txt")); osw.write("Hello World 中国"); osw.close(); //用FileWriter写出 FileWriter writer=new FileWriter("a.txt"); writer.write("Hello World"); writer.close();
2、字符输入流 InputStreamReader 、FileReader
a、InputStreamReader
构造方法:
InputStreamReader(InputStream in) :按默认编码读取
InputStreamReader(InputStream in,String charsetName) :按指定编码读取
b、FileReader--------FileReader继承自InputStreamReader
构造方法:
FileReader(File file)
FileReader(String name)
用法:
//用InputStreamReader读取 InputStreamReader reader=new InputStreamReader(new FileInputStream("a.txt")); char[] chars=new char[1024]; int len=0; while ((len=reader.read(chars))!=-1){ System.out.print(new String(chars,0,len)); } reader.close(); //用FileReader读取 FileReader fileReader=new FileReader("a.txt"); char[] chars1=new char[1024]; int len1=0; while ((len=fileReader.read(chars1))!=-1){ System.out.print(new String(chars1,0,len)); } fileReader.close();
3、字符缓存输出流 BufferedWriter
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
BufferedWriter bw=new BufferedWriter(new FileWriter("a.txt")); bw.write("Hello World"); bw.flush(); bw.close();
4、字符缓存输入流 BufferedReader
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
BufferedReader br=new BufferedReader(new FileReader("a.txt")); char[] chars2=new char[1024]; int len2=0; while ((len=br.read(chars2))!=-1){ System.out.print(new String(chars2,0,len2)); } br.close(); //BufferedReader还提供了按行读取的功能readLine BufferedReader br1=new BufferedReader(new FileReader("a.txt")); String s=""; while ((s=br1.readLine())!=null){ System.out.print(s); } br1.close();