JAVA的字节流和字符流

本文摘抄于网络,用于梳理总结记忆~~


       在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。
        所有文件的储存是都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘。在读取文件(特别是文本文件)时,也是一个字节一个字节地读取以形成字节序列。

       字节流处理单元为1个字节,操作字节和字节数组;字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串。如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点。 

        字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的;字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容。 


      InputStream 和OutputStream,两个是为字节流设计的,主要用来处理字节或二进制对象,
      Reader和 Writer.两个是为字符流(一个字符占两个字节)设计的,主要用来处理字符或字符串.

       inputStream的read()虽然也返回int,但由于此类是面向字节流的,一个字节占8个位,所以返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。因此对于不能用0-255来表示的值就得用字符流来读取!比如说汉字.

      Reader类的read()方法返回类型为int :作为整数读取的字符(占两个字节共16位),范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1



一、字节流(InputStream, OutputStream)

字节流处理单元为 1 个字节,操作字节和字节数组。
InputStream 和 OutputStream 是两个 abstact 类,对于字节为导向的 stream 都扩展这两个基类;
JAVA的字节流和字符流_第1张图片

JAVA的字节流和字符流_第2张图片
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;

 public class Test11 {
     public static void main(String[] args) throws IOException {
         File f = new File("d:" + File.separator+"test.txt");
         OutputStream out=new FileOutputStream(f);//如果文件不存在会自动创建
         String str="Hello World";
         byte[] b=str.getBytes();
         out.write(b);//因为是字节流,所以要转化成字节数组进行输出
         out.close();
     }
 }


 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;

 public class Test12 {
     public static void main(String[] args) throws IOException {
         File f = new File("d:" + File.separator+"test.txt");
         InputStream in=new FileInputStream(f);
         byte[] b=new byte[1024];
         int len=in.read(b);
         in.close();
         System.out.println(new String(b,0,len));
     }
 }



二、字符流(Reader, Writer)

字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串。
以 Unicode 字符为导向的 stream ,表示以 Unicode 字符为单位从 stream 中读取或往 stream 中写入信息。Reader/Writer 为 abstact 类。以 Unicode 字符为导向的 stream 包括下面几种类型:


JAVA的字节流和字符流_第3张图片
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.Writer;

 public class Test16 {
     public static void main(String[] args) throws IOException {
         File f = new File("d:" + File.separator+"test.txt");
         Writer out=new FileWriter(f);
         String str="Hello World";
         out.write(str);
         out.close();
     }
 }


 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.Reader;

 public class Test18 {
     public static void main(String[] args) throws IOException {
         File f = new File("d:" + File.separator+"test.txt");
         Reader input=new FileReader(f);
         char[] c=new char[1024];
         int len=input.read(c);
         input.close();
         System.out.println(new String(c,0,len));
     }
 }




三、字节流转字符流(InputStreamReader, OutputStreamWriter)

InputStreamReader 和 OutputStreamReader :把一个以字节为导向的 stream 转换成一个以字符为导向的 stream 。
比如,InputStreamReader类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。InputStreamReader 的 read()方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。



四、缓冲流(BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter)

BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter都是为了提供读写的效率而设计的。
BufferedReader和BufferedWriter类各拥有8192字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。



五、使用原则:

一、按数据来源(去向)分类:
1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 ) 
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 ) 
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 ) 
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 ) 
5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 ) 
二、按是否格式化输出分: 
1 、要格式化输出: PrintStream, PrintWriter 
三、按是否要缓冲分: 
1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 ) 
四、按数据格式分: 
1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类 
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类 
五、按输入输出分: 
1 、输入: Reader, InputStream 类型的子类 
2 、输出: Writer, OutputStream 类型的子类 
六、特殊需要: 
1 、从 Stream 到 Reader,Writer 的转换类: InputStreamReader, OutputStreamWriter 
2 、对象输入输出: ObjectInputStream, ObjectOutputStream 
3 、进程间通信: PipeInputStream, PipeOutputStream, PipeReader, PipeWriter 
4 、合并输入: SequenceInputStream 
5 、更特殊的需要: PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader 
七、决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要):
第一,考虑最原始的数据格式是什么: 原则四
第二,是输入还是输出:原则五
第三,是否需要转换流:原则六第 1 点
第四,数据来源(去向)是什么:原则一
第五,是否要缓冲:原则三 (特别注明:一定要注意的是 readLine() 是否有定义,有什么比 read, write 更特殊的输入或输出方法)
第六,是否要格式化输出:原则二

你可能感兴趣的:(java,android,Inputstream,BufferReader,reader)