IO流2

IO流二

字符流

计算机并不区分二进制文件与文本文件。所有的文件都是以二进制形式来存储的,因此,从本质上说,所有的文件都是二进制文件。所以字符流是建立在字节流之上的,它能够提供字符层次的编码和解码。例如,在写入一个字符时,Java虚拟机会将字符转为文件指定的编码(默认是系统默认编码),在读取字符时,再将文件指定的编码转化为字符。

常见的码表如下:

ASCII: 美国标准信息交换码。 一个字符占一个字节。
ISO8859-1: 拉丁码表。欧洲码表,用一个字节的8位表示。又称Latin-1(拉丁编码)或“西欧语言”。ASCII码是包含的仅仅是英文字母,并且没有完全占满256个编码位置,所以它以ASCII为基础,在空置的0xA0-0xFF的范围内,加入192个字母及符号集以供使用变音符号的拉丁字母语言使用。从而支持德文,法文等。因而它依然是一个单字节编码,只是比ASCII更全面。

GB2312: 英文占一个字节,中文占两个字节.中国的中文编码表。

GBK: GBK 是 GB2312的扩展 ,除了兼容GB2312外,它还能显示繁体中文,还有日文的假名。。 中国的中文编码表升级,融合了更多的中文文字符号。

Unicode: 国际标准码规范,融合了多种文字。所有文字都用两个字节来表示,Java语言使用的就是unicode。

UTF-8: 英文一个字节, 中文三个字节。 最多用三个字节来表示一个字符。
(我们以后接触最多的是iso8859-1、gbk、utf-8)

字节流可以拷贝视频和音频等文件,那么字符流可以拷贝这些吗?

经过验证拷贝图片是不行的。发现丢失了信息,为什么呢?

计算机中的所有信息都是以二进制形式进行的存储(1010)图片中的也都是二进制
在读取文件的时候字符流自动对这些二进制按照码表进行了编码处理,但是图片本来就是二进制文件,不需要进行编码。有一些巧合在码表中有对应,就可以处理,并不是所有的二进制都可以找到对应的。信息就会丢失。所以字符流只能拷贝以字符为单位的文本文件
(以ASCII码为例是127个,并不是所有的二进制都可以找到对应的ASCII,有些对不上的,就会丢失信息。)

Reader

实现类FileReader构造
FileReader(File file) 
      在给定从中读取数据的 File 的情况下创建一个新 FileReader。 
FileReader(String fileName) 
      在给定从中读取数据的文件名的情况下创建一个新 FileReader。 

int read() 
      读取单个字符。 
int read(char[] cbuf) 
      将字符读入数组。 
abstract  int read(char[] cbuf, int off, int len) 
      将字符读入数组的某一部分。 此类在Reader的子类FileReader的类inoutStreamReader中实现

/**
 * 使用字节流读取文件内容
 * 
 * @param path
 */
public static void readFileByInputStream(String path) throws Exception {
    InputStream in = new FileInputStream(path);

    int len = 0;
    while ((len = in.read()) != -1) {
        System.out.print((char) len);
    }

    in.close();
}
/**
 * 使用字符流读取文件内容
 */
public static void readFileByReader(String path) throws Exception {
    Reader reader = new FileReader(path);
    int len = 0;
    while ((len = reader.read()) != -1) {
        System.out.print((char) len);
    }

    reader.close();
}

Writer

子类FileWriter中的构造
FileWriter(File file) 
      根据给定的 File 对象构造一个 FileWriter 对象。 
FileWriter(File file, boolean append) 
      根据给定的 File 对象构造一个 FileWriter 对象。 
FileWriter(String fileName) 
      根据给定的文件名构造一个 FileWriter 对象。 
FileWriter(String fileName, boolean append) 
      根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。 

abstract  void close() 
      关闭此流,但要先刷新它。 
abstract  void flush() 
      刷新该流的缓冲。 
void write(char[] cbuf) 
      写入字符数组。 
abstract  void write(char[] cbuf, int off, int len) 
      写入字符数组的某一部分。 
void write(int c) 
      写入单个字符。 
void write(String str) 
      写入字符串。 
void write(String str, int off, int len) 
      写入字符串的某一部分。 

/**
 * 写指定数据到指定文件中
 * 
 */
public static void writeToFile(String path) throws Exception {
    Writer writer = new FileWriter(path);
    writer.write('中');
    writer.write("世界".toCharArray());
    writer.write("中国");

    writer.close();
}

追加文件:

默认的FileWriter方法新值会覆盖旧值,想要实现追加功能需要
使用如下构造函数创建输出流 append值为true即可。
FileWriter(String fileName, boolean append)
FileWriter(File file, boolean append)

flush方法:
如果使用字符输出流,没有调用close方法,数据将不会写入文件,可调用flush方法继续输入

private static void writeFileByWriter(File file) throws IOException {
    FileWriter fw = new FileWriter(file);
    fw.write('新');
    fw.flush();
    fw.write("中国".toCharArray());
    fw.write("世界你好!!!".toCharArray());
    fw.write("明天"); 
    // 关闭流资源
    //fw.close();
}

字符流拷贝文件

public static void copyFile3(String path1, String path2) throws Exception {
    Reader reader = new FileReader(path1);
    Writer writer = new FileWriter(path2);

    int ch = -1;
    char [] arr=new char[1024];
    while ((ch = reader.read(arr)) != -1) {
        writer.write(arr,0,ch);
    }

    reader.close();
    writer.close();
}

字符流的异常处理

/**
 * 使用字符流拷贝文件,有完善的异常处理
 */
public static void copyFile2(String path1, String path2) {
    Reader reader = null;
    Writer writer = null;
    try {
        // 打开流
        reader = new FileReader(path1);
        writer = new FileWriter(path2);

        // 进行拷贝
        int ch = -1;
        while ((ch = reader.read()) != -1) {
            writer.write(ch);
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    } finally {
        // 关闭流,注意一定要能执行到close()方法,所以都要放到finally代码块中
        try {
            if (reader != null) {
                reader.close();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}

你可能感兴趣的:(IO流2)