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);
            }
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,719评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,337评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,887评论 0 324
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,488评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,313评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,284评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,672评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,346评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,644评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,700评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,457评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,316评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,706评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,261评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,648评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,859评论 2 335

推荐阅读更多精彩内容