字节流与字符流小结

来源:互联网 发布:扎克伯格娶丑女知乎 编辑:程序博客网 时间:2024/06/05 22:40

                                                  字节流与字符流小结

字节流

顾名思义

以字节为单位进行IO操作

最大的两个父类是

InputStream与OutputStream

都是抽象类

需要通过多态

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

字符流

顾名思义

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

一个字符为两个字节

最大的两个父类为

Writer和Reader这两个抽象类

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

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

只是在传入参数部分

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

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

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

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

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

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


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

     上面两点能说明什么呢?

        针对第一点,

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

       针对第二点,

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

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

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

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

Java代码
  1. import java.io.File; 
  2. import java.io.FileNotFoundException; 
  3. import java.io.FileWriter; 
  4. import java.io.IOException; 
  5. import java.io.Writer; 
  6.  
  7. public class WriterTest { 
  8.     /**
  9.      * @param args
  10.      */ 
  11.     public staticvoid main(String[] args) { 
  12.         // TODO Auto-generated method stub 
  13.           try
  14.               File f=new File("E:"+File.separator+"test.txt"); 
  15.             Writer writer=new FileWriter(f); 
  16.             writer.write("Hello World"); 
  17.              
  18.         } catch (FileNotFoundException e) { 
  19.             // TODO Auto-generated catch block 
  20.             e.printStackTrace(); 
  21.         } catch (IOException e) { 
  22.             // TODO Auto-generated catch block 
  23.             e.printStackTrace(); 
  24.         } 
  25.     } 

查看FileWriter源码

 

        Java代码
  1. package java.io; 
  2.  
  3. public class FileWriterextends OutputStreamWriter { 
  4.     public FileWriter(String fileName)throws IOException { 
  5.     super(new FileOutputStream(fileName)); 
  6.     } 
  7.     public FileWriter(String fileName,boolean append) throws IOException { 
  8.     super(new FileOutputStream(fileName, append)); 
  9.     } 
  10.  
  11.     public FileWriter(File file) throws IOException { 
  12.     super(new FileOutputStream(file)); 
  13.     } 
  14.  
  15.     public FileWriter(File file, boolean append) throws IOException { 
  16.         super(new FileOutputStream(file, append)); 
  17.     } 
  18.     public FileWriter(FileDescriptor fd) { 
  19.     super(new FileOutputStream(fd)); 
  20.     } 
  21.  

可以轻松发现

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

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

继续查看OutputWriter中代码

Java代码
  1. package java.io; 
  2.  
  3. import java.nio.charset.Charset; 
  4. import java.nio.charset.CharsetEncoder; 
  5. import sun.nio.cs.StreamEncoder; 
  6.  
  7.  
  8. public class OutputStreamWriterextends Writer { 
  9.  
  10.     private final StreamEncoder se; 
  11.  
  12.     public OutputStreamWriter(OutputStream out, String charsetName) 
  13.     throws UnsupportedEncodingException 
  14.     { 
  15.     super(out); 
  16.     if (charsetName == null
  17.         throw new NullPointerException("charsetName"); 
  18.     se = StreamEncoder.forOutputStreamWriter(out, this, charsetName); 
  19.     } 
  20.     public void write(String str,int off, int len)throws IOException { 
  21.     se.write(str, off, len); 
  22.     } 

我们发现:

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

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

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

 

原创粉丝点击