难道这两天不是特别忙
静下心来复习复习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()方法,通过字节流输出
以上只分析了输出流,显然,对于输入流,道理是相同的