流的概念
流是一个很抽象的概念,当程序需要读写数据时,就会开启一个通向数据源的流,这个数据源可以是文件、内存或者网络连接,在程序读写数据过程中,数据就像在“流”动一样。
由上图可知,流代表经过管道流通的数据。为了进行数据的输入和输出操作,JAVA把不同的输入和输出源(例如键盘、文件和网络连接等)抽象表述为流。
按流向不同,可以分为输入流和输出流。按处理单位不同,可以分为字节流(在数据读取和写入时以字节为单位)和字符流(在数据读取和写入时以字符为单位)。
字节流包括InputStream和OutputStream两个基础类。字符流包括Reader和Writter两个基础类。
字节与字符的概念
字节:通过网络传输信息(或硬盘、内存中存储信息)的单位。字节是用于计量存储容量和传输容量的一种计量单位,1个字节等于8个二进制位。是一个很具体的存储空间。
字符:人们使用的记号,符号。 如'1', '中', 'a', '$', '¥', ……
下面是几种不同编码方式中字符和字节的对应关系:
①、ASCII码中,一个英文字母(不分大小写)占1个字节的空间,一个中文汉字占2个字节。
②、Unicode编码中,一个英文和一个中文都占2个字节。
③、UTF-8编码中,一个英文字符1个字节,一个中文字符3个字节。
字节流和字符流之间的转化
一般在处理图片、多媒体等原始字节信息时,选用字符流,如FileInputStream/FileOutputStream等。如果文件包含的是字符信息,应选用字符流,例如FileReader、FileWriter等。在字符流和字节流相互转化时下需要注意编码问题,如果使用错误的编码格式,流信息将会失真,出现乱码。
InputStreamReader是字节流通向字符流的桥梁,可以完成字节流向字符流的转化。它使用指定的字符集读取字节并将其解码为字符。为提高效率,可以考虑使用BufferedReader包装InputStreamReader。
package test.io;
import java.io.BufferedReader;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;
public class Test { public static void main(String[] args) { FileInputStream fis = null; InputStreamReader isr = null; BufferedReader br = null;
try { fis = new FileInputStream("D:\\1.txt"); isr = new InputStreamReader(fis, "UTF-16LE"); br = new BufferedReader(isr); String content = br.readLine(); System.out.println(isr.getEncoding() + ";" +content); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
if(br != null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
if(isr != null){ try { isr.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
if(fis != null){ try { fis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
OutputStreamWriter是字符流通向字节流的桥梁,可以完成字符流到字节流的转化。通过BufferedWriter对OutputStreamWriter进行包装,提高效率。
private void writeFile() { // TODO Auto-generated method stub FileOutputStream fos = null; OutputStreamWriter osw = null; BufferedWriter bw = null;
try { fos = new FileOutputStream("D:\\1.txt"); osw = new OutputStreamWriter(fos, "UTF-8"); bw = new BufferedWriter(osw);
bw.write("测试输入输出流。"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try{ if(bw != null){ bw.close(); }
if(osw != null){ osw.close(); }
if(fos != null){ fos.close(); } }catch (IOException e) { // TODO: handle exception }
}
}
使用close()方法会默认执行flush()方法,将缓冲区信息输出。