<笔记>字符流和字节流的区别 加入了自己的理解


【以下正文】

1 . 之前

○ 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。
○ 程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。

2 . 字节流与字符流

○ 在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。
○ 在字节流中输出数据主要是使用OutputStream类完成,输入数据主要是使用InputStream类完成——主要用于处理字节或二进制对象。(byte[])
○ 在字符流中输出数据主要是使用Writer类完成,输入数据主要是使用Reader类完成——主要用于处理字符或字符串。(String)
○ 字节流可以处理任何类型的对象,包括二进制对象。但是它不能直接处理Unicode字符。
○ 字符流可以处理Unicode字符、字符串之类的。但是它处理不了对象。
○ 1字符 = 2字节。

○ 字符流的处理单元为2个字节的Unicode字符,字节流的处理单元为1个字节。
○ JAVA虚拟机负责(用encode)将字节转化为2个字节的Unicode字符。字节流构造字符流。这实质就是String和byte[]的关系转换。
○ 这是通过InputStreamReader和OutputStreamWriter完成的。(记忆:正好是InputSteam+Reader和OutputStream+Writer)

○ 文件在磁盘上的保存方式不是存储字符,而是将字符编码成字节存储。因此读取和写入文件时,都是操作字节。

3 . 操作字节流/字符流的流程

①使用File类打开一个文件
②通过字节流/字符流的子类,指定输出位置
③做读/写操作
④最后关闭输入/输出流。因为这属于资源操作,因此一定要关闭,释放资源。

==============

4 . 举例子:

站在内存和文件的关系角度理解。

○ 内存→文件:为“写文件操作”,用OutputStream(字节流)和Writer(字符流)。
○ 内存←文件:为“读文件操作”,用InputStream(字节流)和Reader(字符流)。


【字节流·写】OutputStream的子类FileOutputStream类
写一个字符串到某个txt文件中:利用OutputStream类(由于它被定义为abstract的,因此必须由子类实例化对象再去操作,即FileOutputStream类)

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class WriteStr{
    public static void main(String args[]) throws IOException {    //注意,要抛出一个文件找不到的IO异常

        Output out = new FileOutputStream(f);    
        //因为是对一个文件做读写操作,因此用File类的OutputStream。注意,对于FileOutputStream(f),再调用时,会覆盖newFile.txt内容。若想追加内容,使用另一个构造函数FileOutputStream(File file, boolean append)。即FileOutputStream(f, true)就可以继续在newFile.txt中追加内容了

        String str = "The line to be writed into txt file.";    //准备写入的字符串。另,“\r\n”可以用来表示换行符

        byte[] b = str.getBytes();    //因为文件的读写都是对字节操作的,因此必须完成一个字符到字节的转换。利用getBytes可以做到。

        out.write(b);    //write()函数起到将字节流输出的作用
        out.close();    //必须关闭IO操作,释放资源
    }
}

【字节流·读】InputStream类的子类FileInputStream类
从一个txt文件中读一串字符串:利用InputStream类(由于它被定义为abstract的,因此必须由子类实例化对象再去操作,及FileInputStream类)

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

public class ReadStr{
    public static void main(String args[]) throws IOException {    //注意,要抛出一个文件找不到的IO异常

        File f = new File("e:" + File.seperator + "newFile.txt");    //同上,利用变量f存放文件信息

        Input in = new FileInputStream(f);    //同上

        byte[] b = new byte[(int) f.length()];    //注意:①new byte[...]了;②f.length()是预定义的函数,自动获取f的文件长度;③对f.length()需要强制转换为int型

        String str = new String(b);    //注意,与写入文件不同的地方。需要把byte字节型,转换成String字符型写进来

        in.read(b);
        in.close();
        System.out.println(str);    //同样,打印str就可以了。
    }
}

【字符流·写】Writer类的子类FileWriter类
写一个字符串到某个txt文件中:利用Writer类(由于它被定义为abstract的,因此必须由子类实例化对象再去操作,即FileWriter类)

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class WriteStr{
    public static void main(String args[]){
        File f = new File("e:" + File.seperator + "newFile.txt");    //同样需要先获取文件信息,存到变量f中

        Writer out = new FileWriter(f, true);    //true表示写文件的时候不是覆盖原来的,而是追加到末尾

        String str = "Hello World!";
        out.write(str);    //直接写入字符串str就可以了。字符流可以直接操作,不需要转换成byte型

        out.close();    //释放IO资源
    }
}

【字符流·读】Reader类的子类FileReader类
从一个txt文件中读一串字符串:利用Reader类(由于它被定义为abstract的,因此必须由子类实例化对象再去操作,及FileReader类)

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

public class ReadStr{
    public static void main(String args[]){
        File f = new File("e:" + File.seperator + "newFile.txt");
        Reader in = new FileReader(f);

        char[] c = new char[1024];    //因为读出来的是byte字节数组,因此要转化成一个字符数组输出,先new一块空间

        int len = in.read(c);    //需要确定文件内文本的长度
        in.close();    //释放IO资源,字符流不先释放IO资源,无法打印
        System.out.println(new String(c, 0, len));    //因为读出来的内容还是字节流byte数组,因此要转化成字符流String数组
    }
}

5 . 字符流和字节流在内存方面的区别:

○ 字节流直接操作文件,不经过内存;
○ 字符流间接操作文件,经过内存,再到文件。
○ 字节流即使不close()操作,也可以写入文件;
○ 字符流如果不先close()操作,只会存在内存的缓冲区,不会写入文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值