黑马程序员 Java基础知识总结-IO流


IO按操作数据分可分为:字节流和字符流。

字节流:用于处理字节的对象为字节流,即能处理字节流的对象。

字符流:字节流读取文字字节之后,不直接操作而是先查制定的编码表,获取相应的文字,再对这个文字进行操作,简单的说:字符流=字节流+编码表。

字节流的抽象基类:InputStream ,OutputStream

字符流的抽象基类:Reader  , Writer

输入字节流InputStream:InputStream 是所有的输入字节流的父类,是一个抽象类。ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的输入流(数据源),它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据。ObjectInputStream 和所有FilterInputStream 的子类都是装饰流。

输出字节流OutputStream:OutputStream 是所有的输出字节流的父类,它是一个抽象类。ByteArrayOutputStream、FileOutputStream 是两种基本的输出流(输出的目标地点),它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据。ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流。

字符输入流Reader:Reader 是所有的输入字符流的父类,它是一个抽象类。CharArrayReader、StringReader是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader是从另外一个InputStream作为数据源读入数据。BufferedReader 是一个装饰器,它和其子类负责装饰其它Reader 对象,从而大道输入有缓冲的效果(一般自己加入缓冲区)。InputStreamReader 是一个字节输入流转换字符输出流的桥梁,提供字节输入流转换成字符出入流。FileReader 可以说是一个达到此功能、常用的工具类。字符输出流Writer:Writer 是所有的输出字符流的父类,它是一个抽象类。CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据。BufferedWriter 是一个装饰器为Writer 提供缓冲功能。PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。OutputStreamWriter 是字节输出流(OutputStream)到字符输出流(Writer) 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类。功能和使用和OutputStream 类似。

转换流的特点:

  1. 其是字符流和字节流之间的桥梁
  2. 可对读取到的字节数据经过指定编码转换成字符
  3. 可对读取到的字符数据经过指定编码转换成字节

使用转换流的场景?

  1. 当字节和字符之间有转换动作时;
  2. 流操作的数据需要编码或解码时。

具体的对象体现:

  1. InputStreamReader:字节到字符的桥梁
  2. OutputStreamWriter:字符到字节的桥梁

这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来。

如何使用转换流:

以字节输入流转换成字符输出流为例:BuffreedReader buffr = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));将一个字节输入流转换成了一个字符输出流。

【注】若操作文字数据建议优先考虑字符流,而且要将数据写到硬盘上,要是用字符流中的输入输出流Writer

例1:复制一个文本文件到目标位置。

package com.blog.source;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyFile {

	/**
	 * 复制文件 
	 */
	public static void main(String[] args) {
		copyFileMethod();
	}

	public static void copyFileMethod() {
		//创建一个字符输入流对象
		FileReader fr = null;
		//创建一个字符输出流对象
		FileWriter fw = null;
		//自定义缓冲区
		char[] cbuf = new char[1024];
		int len = 0 ;
		try {
			//实例化输入流对象
			fw = new FileWriter("copy_a.txt");
			//实例化输出流对象
			fr = new FileReader("a.txt");
			//开始读数据
			while ((len = fr.read(cbuf, 0, 1024)) != -1) {
				fw.write(cbuf, 0, len);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fr != null) {
				try {
					//关闭流对象
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fw != null) {
				try {
					//关闭流对象
					fw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
在上面的例子中使用了字符输入流和字符输出流对象,假定当前目录下有a.txt文件,上述程序会执行成功。在上面程序中使用了自定义缓冲区cbuf。java中也提供了这样的流对象,BufferedReader和BufferedWriter。加入缓冲区的目的是为了程序的高效。

例2:复制一个媒体文件到目标位置。

分析,字符流=字节流+编码表。也就是说文字字符的时候可以使用字符流,若使用上面的程序去复制任意一个媒体格式文件,都会成功但是复制的文件不能被正确打开。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyMediaFile { 
	public static void main(String[] args) {
		copyMediaFileMethod();
	}
	public static void copyMediaFileMethod(){
		FileInputStream fin = null ; 
		FileOutputStream fos = null ;
		try {
			//实例化流对象
			fin = new FileInputStream("IO.jpg");
			fos = new FileOutputStream("a_copy.jpg");
			//创建缓冲区
			byte[] buf = new byte[1024];
			int len = 0 ;
			//复制文件
			while((len = fin.read(buf, 0, 1024)) != -1){
				fos.write(buf, 0, len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(fin!=null){
				try {
					fin.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fos!=null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

上面例子描述的额是使用字节流复制媒体文件。同样,假定当前目录下存在IO.jpg文件。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值