1、字符流:

字节流不能操作Unicode字符,由于Java采用16位的Unicode字符,即一个字符占16位,所以要使用基于字符的输入输出操作。所以创造了字符流,以提供直接的字符输入输出的支持。

2、字符流类的层次结构:
2.1、输入流的类层次结构:

2.2、输出流的类层次结构

3、字符流的顶层抽象类:

Reader和Writer。

public abstract class Reader extends Object implements Readable, Closeable

用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

public abstract class Writer extends Object implements Appendable, Closeable, Flushable

写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

4、java.io包中用于处理字符流的基本类InputStreamReader和OutputStreamWriter:

InputStreamReader是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

4.1、InputStreamReader主要构造方法:
InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。 InputStreamReader(InputStream in, Charset cs) 创建使用给定字符集的 InputStreamReader。 InputStreamReader(InputStream in, CharsetDecoder dec) 创建使用给定字符集解码器的 InputStreamReader。 InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。
4.2、OutputStreamWriter主要构造方法:
OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。 OutputStreamWriter(OutputStream out, Charset cs) 创建使用给定字符集的 OutputStreamWriter。 OutputStreamWriter(OutputStream out, CharsetEncoder enc)创建使用给定字符集编码器的 OutputStreamWriter。 OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。
5、字符流的使用例子:
5.1、下面使用了一些常用的字符流对象实现文件的输出和输入:
public static void main(String[] args) throws IOException {

    //创建文件字节输出流
    FileOutputStream fos = new FileOutputStream("D:/itzhai/arthinking.txt");
    //把字节输出流转换成字符输出流,并使用了BufferedWriter提供缓冲功能
    BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(fos));
    bw.write("arthinking");
    bw.close();

    //创建文件字节输入流
    FileInputStream fis = new FileInputStream("D:/itzhai/arthinking.txt");
    //把字节输入流转换成字符输入流,并使用了BufferedReader提供缓冲功能
    BufferedReader br = new BufferedReader(
            new InputStreamReader(fis));
    String str = br.readLine();
    while(null != str){
        System.out.println(str);
        str = br.readLine();
    }
    br.close();
}
5.2、下面把标准的输入流封装成字符流并添加缓冲功能:

标准的输出流和标准的输入流是字节流:

static InputStream in “标准”输入流。 static PrintStream out “标准”输出流。
public static void main(String[] args) throws IOException {

    BufferedReader br = new BufferedReader(
            new InputStreamReader(System.in));
    String str;
    while(null != (str = br.readLine())){
        System.out.println(str);
    }
}
5.3、FileReader和FileWriter的使用:
public class FileReader extends InputStreamReader

用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。

FileReader 用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream。

public class FileWriter extends OutputStreamWriter

用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。要自己指定这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter。

文件是否可用或是否可以被创建取决于底层平台。特别是某些平台一次只允许一个 FileWriter(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。

FileWriter 用于写入字符流。要写入原始字节流,请考虑使用 FileOutputStream。

使用FileReader和FileWriter读取文件和写出文件:
public static void main(String[] args) throws IOException {

    String str = "hello world!!!";
    //创建字符数组并初始化
    char[] buffer = new char[str.length()];
    str.getChars(0, str.length(), buffer, 0);
    //创建FileWriter
    FileWriter fw = new FileWriter("D:/itzhai/arthinking.txt");
    //逐个字符的输出到文件
    for(int i=0; i<buffer.length; i++){
        fw.write(buffer[i]);
    }
    fw.close();

    //创建FileReader
    BufferedReader br = new BufferedReader(
            new FileReader("D:/itzhai/arthinking.txt"));
    //使用BufferedReader提供的逐行读取函数读取文件
    while(null != (str = br.readLine())){
        System.out.println(str);
    }
    br.close();
}
5.4、CharArrayReader和CharArrayWriter的使用
public class CharArrayReader extends Reader

此类实现一个可用作字符输入流的字符缓冲区。

public class CharArrayWriter extends Writer

此类实现一个可用作 Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。可使用 toCharArray() 和 toString() 获取数据。

注:在此类上调用 close() 无效,并且在关闭该流后可以调用此类中的各个方法,而不会产生任何 IOException。

下面使用CharArrayReader读取字符数组:
public static void main(String[] args) throws IOException {

    String str = "arthinking";
    //创建并初始化字符数组
    char[] ch = new char[str.length()];
    str.getChars(0, str.length(), ch, 0);

    //通过字符数组初始化字符数组输入流
    CharArrayReader cr = new CharArrayReader(ch);

    int c;
    while(-1 != (c = cr.read())){
        System.out.print((char)c);
    }
}
5.5、RandomAccessFile的使用:
public class RandomAccessFile extends Object implements DataOutput, DataInput, Closeable

此类的实例既可以支持对随机访问文件的读取也可以支持对其写入。

随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。

public static void main(String[] args) throws IOException {

    //创建随机访问文件
    RandomAccessFile raf = new RandomAccessFile("D:/itzhai/arthinking.txt", "rw");
    //写入数据
    raf.writeInt(1);
    raf.writeChar('a');
    //文件指针复位
    raf.seek(0);
    //输出数据
    System.out.println(raf.readInt() + "" + raf.readChar());
}
6、字符集编码介绍:
ASCII:

它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO 646。可显示字符:英文大小写字符、阿拉伯数字和西文符号。

ISO-8859-1:

是四方国家所使用的编码机,单字节的字符集。

GB2312:

GB2312是中国国家标准的简体中文字符集。它所收录的汉字已经覆盖99.75%的使用频率,基本满足了汉字的计算机处理需要。在中国大陆和新加坡获广泛使用。

GBK:

除了完全兼容GB2312之外,还对繁体中文,不常用汉字和特殊符号进行了编码。

UTF-8:

UTF-8便于不同的计算机之间使用网络传输不同语言和编码的文字,使得双字节的Unicode能够在现存的处理单字节的系统上正确传输。

UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1字节储存,重音文字、希腊字母或西里尔字母等使用2字节来储存,而常用的汉字就要使用3字节。辅助平面字符则使用4字节。

Unicode:

一种通用字符集,每个字符都用2个字节来表示,对于英文字符采用前面补0的方法实现等长兼容。

除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。 本文链接:http://www.itzhai.com/java-based-notes-character-stream-classification-and-detailed-description-of-various-character-stream-classes-with-the-use-of-character-sets.html
 
分类: java