字节流与字符流小结

难道这两天不是特别忙

静下心来复习复习JAVA基础

抽空好好回顾了下IO方面的知识

主要是关于字节流与字符流的一个总结

 

字节流

顾名思义

以字节为单位进行IO操作

最大的两个父类是

InputStream与OutputStream

都是抽象类

需要通过多态

初始化具体实现的子类来进行读写操作

 

字符流

顾名思义

是以字符为单位进行IO操作的

一个字符为两个字节

最大的两个父类为

Writer和Reader这两个抽象类

 

当就字节流与字符流抽象类中的方法来看

其实方法名,返回值类型等都很相似

只是在传入参数部分

字节流的write()方法需要传入的是字节数组

字符流的write()方法需要传入的是字符数组(String也算字符数组?)

 

但是我们都知道字符数组和字节数组是很容易通过getBytes()和new String()来互换的

 

字节流和字符流的根本区别显然不在此处

 

那么到底字节流和字符流的主要区别是什么呢?

           一.字节流在操作时不会用到缓冲区(内存),是直接对文件本身进行操作的。而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。


           二.在硬盘上的所有文件都是以字节形式存在的(图片,声音,视频),而字符值在内存中才会形成。

 

 

     上面两点能说明什么呢?

        针对第一点,

       我们知道,如果一个程序频繁对一个资源进行IO操作,效率会非常低。此时,通过缓冲区,先把需要操作的数据暂时放入内存中,以后直接从内存中读取数据,则可以避免多次的IO操作,提高效率

       针对第二点,

       真正存储和传输数据时都是以字节为单位的,字符只是存在与内存当中的,所以,字节流适用范围更为宽广

 

 

        三。字符流其实是通过转换流变化为字节流再进行IO操作

 

       我们知道Reader和Writer都是抽象类,要进行具体的操作,都需要通过多态,利用具体实现的类中具体实现的方法进行操作

       比如,我们适用字符流向文件中写入字符串,可能的代码如下

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class WriterTest {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
          try {
        	  File f=new File("E:"+File.separator+"test.txt");
			Writer writer=new FileWriter(f);
			writer.write("Hello World");
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 查看FileWriter源码

package java.io;

public class FileWriter extends OutputStreamWriter {
    public FileWriter(String fileName) throws IOException {
	super(new FileOutputStream(fileName));
    }
    public FileWriter(String fileName, boolean append) throws IOException {
	super(new FileOutputStream(fileName, append));
    }

    public FileWriter(File file) throws IOException {
	super(new FileOutputStream(file));
    }

    public FileWriter(File file, boolean append) throws IOException {
        super(new FileOutputStream(file, append));
    }
    public FileWriter(FileDescriptor fd) {
	super(new FileOutputStream(fd));
    }

}
 

可以轻松发现

FileWriter并非直接是Writer的子类,而是转换流OutputWriter的子类

FileWriter做的唯一的事:就是根据文件名,得到一个OutputStream,然后通过调用父类的构造器传入转换流OutputWriter中

 

继续查看OutputWriter中代码

package java.io;

import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import sun.nio.cs.StreamEncoder;


public class OutputStreamWriter extends Writer {

    private final StreamEncoder se;

    public OutputStreamWriter(OutputStream out, String charsetName)
	throws UnsupportedEncodingException
    {
	super(out);
	if (charsetName == null)
	    throw new NullPointerException("charsetName");
	se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
    }
    public void write(String str, int off, int len) throws IOException {
	se.write(str, off, len);
    }
}

我们发现:

在转换流中,其实只是通过传入需要转换的字节流来构造一个StreamEncoder类对象

然后调用此StreamEncoder类对象se来完成write()方法,通过字节流输出

 

 

以上只分析了输出流,显然,对于输入流,道理是相同的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值